conflux_pool.c (69977B)
1 /* Copyright (c) 2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /** 5 * \file conflux_pool.c 6 * \brief Conflux circuit pool management 7 */ 8 9 #define TOR_CONFLUX_PRIVATE 10 #define CONFLUX_CELL_PRIVATE 11 12 #include "core/or/or.h" 13 14 #include "app/config/config.h" 15 16 #include "core/or/circuitbuild.h" 17 #include "core/or/circuitlist.h" 18 #include "core/or/circuitstats.h" 19 #include "core/or/circuituse.h" 20 #include "core/or/congestion_control_st.h" 21 #include "core/or/conflux.h" 22 #include "core/or/conflux_cell.h" 23 #include "trunnel/conflux.h" 24 #include "core/or/conflux_params.h" 25 #include "core/or/conflux_pool.h" 26 #include "core/or/conflux_util.h" 27 #include "core/or/relay.h" 28 #include "core/or/connection_edge.h" 29 #include "core/or/edge_connection_st.h" 30 31 #include "core/or/crypt_path_st.h" 32 #include "core/or/or_circuit_st.h" 33 #include "core/or/origin_circuit_st.h" 34 #include "core/or/extend_info_st.h" 35 #include "core/or/conflux_st.h" 36 37 #include "feature/nodelist/nodelist.h" 38 #include "feature/client/bridges.h" 39 #include "app/config/config.h" 40 41 #include "lib/crypt_ops/crypto_rand.h" 42 #include "lib/crypt_ops/crypto_util.h" 43 44 /* Indicate if we are shutting down. This is used so we avoid recovering a 45 * conflux set on total shutdown. */ 46 static bool shutting_down = false; 47 48 /** The pool of client-side conflux_t that are built, linked, and ready 49 * to be used. Indexed by nonce. */ 50 static digest256map_t *client_linked_pool; 51 52 /** The pool of origin unlinked_circuits_t indexed by nonce. */ 53 static digest256map_t *client_unlinked_pool; 54 55 /** The pool of relay conflux_t indexed by nonce. We call these "server" 56 * because they could be onion-service side too (even though we likely will 57 * only implement onion service conflux in Arti). The code is littered with 58 * asserts to ensure there are no origin circuits in here for now, too. */ 59 static digest256map_t *server_linked_pool; 60 61 /** The pool of relay unlinked_circuits_t indexed by nonce. */ 62 static digest256map_t *server_unlinked_pool; 63 64 /* A leg is essentially a circuit for a conflux set. We use this object for the 65 * unlinked pool. */ 66 typedef struct leg_t { 67 /* The circuit of the leg. */ 68 circuit_t *circ; 69 70 /* The LINK cell content which is used to put the information back in the 71 * conflux_t object once all legs have linked and validate the ack. */ 72 conflux_cell_link_t *link; 73 74 /* Indicate if the leg has received the LINKED or the LINKED_ACK cell 75 * depending on its side of the circuit. When all legs are linked, we then 76 * finalize the conflux_t object and move it to the linked pool. */ 77 bool linked; 78 79 /* What time did we send the LINK/LINKED (depending on which side) so we can 80 * calculate the RTT. */ 81 uint64_t link_sent_usec; 82 83 /* The RTT value in usec takend from the LINK <--> LINKED round trip. */ 84 uint64_t rtt_usec; 85 } leg_t; 86 87 /* Object used to track unlinked circuits which are kept in the unlinked pool 88 * until they are linked and moved to the linked pool and global circuit set. 89 */ 90 typedef struct unlinked_circuits_t { 91 /* If true, indicate that this unlinked set is client side as in the legs are 92 * origin circuits. Else, it is on the exit side and thus or circuits. */ 93 bool is_client; 94 95 /* If true, indicate if the conflux_t is related to a linked set. */ 96 bool is_for_linked_set; 97 98 /* Conflux object that will be set in each leg once all linked. */ 99 conflux_t *cfx; 100 101 /* Legs. */ 102 smartlist_t *legs; 103 } unlinked_circuits_t; 104 105 /** Error code used when linking circuits. Based on those, we decide to 106 * relaunch or not. */ 107 typedef enum link_circ_err_t { 108 /* Linking was successful. */ 109 ERR_LINK_CIRC_OK = 0, 110 /* The RTT was not acceptable. */ 111 ERR_LINK_CIRC_BAD_RTT = 1, 112 /* The leg can't be found. */ 113 ERR_LINK_CIRC_MISSING_LEG = 2, 114 /* The set can't be found. */ 115 ERR_LINK_CIRC_MISSING_SET = 3, 116 /* Invalid leg as in not pass validation. */ 117 ERR_LINK_CIRC_INVALID_LEG = 4, 118 } link_circ_err_t; 119 120 #ifdef TOR_UNIT_TESTS 121 digest256map_t * 122 get_unlinked_pool(bool is_client) 123 { 124 return is_client ? client_unlinked_pool : server_unlinked_pool; 125 } 126 127 digest256map_t * 128 get_linked_pool(bool is_client) 129 { 130 return is_client ? client_linked_pool : server_linked_pool; 131 } 132 #endif 133 134 /* For unit tests only: please treat these exactly as the defines in the 135 * code. */ 136 STATIC uint8_t DEFAULT_CLIENT_UX = CONFLUX_UX_HIGH_THROUGHPUT; 137 STATIC uint8_t DEFAULT_EXIT_UX = CONFLUX_UX_MIN_LATENCY; 138 139 /** Helper: Format at 8 bytes the nonce for logging. */ 140 static inline const char * 141 fmt_nonce(const uint8_t *nonce) 142 { 143 return hex_str((char *) nonce, 8); 144 } 145 146 /** 147 * Return the conflux algorithm for a desired UX value. 148 */ 149 static uint8_t 150 conflux_choose_algorithm(uint8_t desired_ux) 151 { 152 switch (desired_ux) { 153 case CONFLUX_UX_NO_OPINION: 154 return CONFLUX_ALG_LOWRTT; 155 case CONFLUX_UX_MIN_LATENCY: 156 return CONFLUX_ALG_MINRTT; 157 case CONFLUX_UX_HIGH_THROUGHPUT: 158 return CONFLUX_ALG_LOWRTT; 159 /* For now, we have no low mem algs, so use minRTT since it should 160 * switch less and thus use less mem */ 161 /* TODO-329-TUNING: Pick better algs here*/ 162 case CONFLUX_UX_LOW_MEM_THROUGHPUT: 163 case CONFLUX_UX_LOW_MEM_LATENCY: 164 return CONFLUX_ALG_MINRTT; 165 default: 166 /* Trunnel should protect us from this */ 167 tor_assert_nonfatal_unreached(); 168 return CONFLUX_ALG_LOWRTT; 169 } 170 } 171 172 /** Return a newly allocated conflux_t object. */ 173 static conflux_t * 174 conflux_new(void) 175 { 176 conflux_t *cfx = tor_malloc_zero(sizeof(*cfx)); 177 178 cfx->ooo_q = smartlist_new(); 179 cfx->legs = smartlist_new(); 180 181 return cfx; 182 } 183 184 static void 185 conflux_free_(conflux_t *cfx) 186 { 187 if (!cfx) { 188 return; 189 } 190 tor_assert(cfx->legs); 191 tor_assert(cfx->ooo_q); 192 193 SMARTLIST_FOREACH_BEGIN(cfx->legs, conflux_leg_t *, leg) { 194 SMARTLIST_DEL_CURRENT(cfx->legs, leg); 195 tor_free(leg); 196 } SMARTLIST_FOREACH_END(leg); 197 smartlist_free(cfx->legs); 198 199 SMARTLIST_FOREACH(cfx->ooo_q, conflux_msg_t *, cell, 200 conflux_relay_msg_free(cell)); 201 smartlist_free(cfx->ooo_q); 202 203 memwipe(cfx->nonce, 0, sizeof(cfx->nonce)); 204 tor_free(cfx); 205 } 206 207 /** Wrapper for the free function, set the cfx pointer to NULL after free */ 208 #define conflux_free(cfx) \ 209 FREE_AND_NULL(conflux_t, conflux_free_, cfx) 210 211 /** Helper: Free function for the digest256map_free(). */ 212 static inline void 213 free_conflux_void_(void *ptr) 214 { 215 conflux_t *cfx = (conflux_t *)ptr; 216 conflux_free(cfx); 217 } 218 219 /** Return a newly allocated leg object containing the given circuit and link 220 * pointer (no copy). */ 221 static leg_t * 222 leg_new(circuit_t *circ, conflux_cell_link_t *link) 223 { 224 leg_t *leg = tor_malloc_zero(sizeof(*leg)); 225 leg->circ = circ; 226 leg->link = link; 227 return leg; 228 } 229 230 /** Free the given leg object. Passing NULL is safe. */ 231 static void 232 leg_free(leg_t *leg) 233 { 234 if (!leg) { 235 return; 236 } 237 if (leg->circ) { 238 tor_free(leg->circ->conflux_pending_nonce); 239 leg->circ->conflux_pending_nonce = NULL; 240 } 241 tor_free(leg->link); 242 tor_free(leg); 243 } 244 245 /** Return a newly allocated unlinked set object for the given nonce. A new 246 * conflux object is also created. */ 247 static unlinked_circuits_t * 248 unlinked_new(const uint8_t *nonce, bool is_client) 249 { 250 unlinked_circuits_t *unlinked = tor_malloc_zero(sizeof(*unlinked)); 251 unlinked->cfx = conflux_new(); 252 unlinked->legs = smartlist_new(); 253 unlinked->is_client = is_client; 254 memcpy(unlinked->cfx->nonce, nonce, sizeof(unlinked->cfx->nonce)); 255 256 return unlinked; 257 } 258 259 /** Free the given unlinked object. */ 260 static void 261 unlinked_free(unlinked_circuits_t *unlinked) 262 { 263 if (!unlinked) { 264 return; 265 } 266 tor_assert(unlinked->legs); 267 268 /* This cfx is pointing to a linked set. */ 269 if (!unlinked->is_for_linked_set) { 270 conflux_free(unlinked->cfx); 271 } 272 SMARTLIST_FOREACH(unlinked->legs, leg_t *, leg, leg_free(leg)); 273 smartlist_free(unlinked->legs); 274 tor_free(unlinked); 275 } 276 277 /** Add the given unlinked object to the unlinked pool. */ 278 static void 279 unlinked_pool_add(unlinked_circuits_t *unlinked, bool is_client) 280 { 281 tor_assert(unlinked); 282 if (is_client) { 283 digest256map_set(client_unlinked_pool, unlinked->cfx->nonce, unlinked); 284 } else { 285 digest256map_set(server_unlinked_pool, unlinked->cfx->nonce, unlinked); 286 } 287 } 288 289 /** Delete the given unlinked object from the unlinked pool. */ 290 static void 291 unlinked_pool_del(unlinked_circuits_t *unlinked, bool is_client) 292 { 293 tor_assert(unlinked); 294 295 if (is_client) { 296 digest256map_remove(client_unlinked_pool, unlinked->cfx->nonce); 297 } else { 298 digest256map_remove(server_unlinked_pool, unlinked->cfx->nonce); 299 } 300 } 301 302 /** Return an unlinked object for the given nonce else NULL. */ 303 static unlinked_circuits_t * 304 unlinked_pool_get(const uint8_t *nonce, bool is_client) 305 { 306 tor_assert(nonce); 307 if (is_client) { 308 return digest256map_get(client_unlinked_pool, nonce); 309 } else { 310 return digest256map_get(server_unlinked_pool, nonce); 311 } 312 } 313 314 /** Delete from the pool and free the given unlinked object. */ 315 static void 316 unlinked_pool_del_and_free(unlinked_circuits_t *unlinked, bool is_client) 317 { 318 tor_assert(unlinked); 319 unlinked_pool_del(unlinked, is_client); 320 unlinked_free(unlinked); 321 } 322 323 /** Add the given conflux object to the linked conflux set. */ 324 static void 325 linked_pool_add(conflux_t *cfx, bool is_client) 326 { 327 tor_assert(cfx); 328 if (is_client) { 329 digest256map_set(client_linked_pool, cfx->nonce, cfx); 330 } else { 331 digest256map_set(server_linked_pool, cfx->nonce, cfx); 332 } 333 } 334 335 /** Delete from the linked conflux set the given nonce. */ 336 static void 337 linked_pool_del(const uint8_t *nonce, bool is_client) 338 { 339 tor_assert(nonce); 340 if (is_client) { 341 digest256map_remove(client_linked_pool, nonce); 342 } else { 343 digest256map_remove(server_linked_pool, nonce); 344 } 345 } 346 347 /** Return a conflux_t object for the given nonce from the linked set. */ 348 static conflux_t * 349 linked_pool_get(const uint8_t *nonce, bool is_client) 350 { 351 tor_assert(nonce); 352 if (is_client) { 353 return digest256map_get(client_linked_pool, nonce); 354 } else { 355 return digest256map_get(server_linked_pool, nonce); 356 } 357 } 358 359 /** Add the given leg to the given unlinked object. */ 360 static inline void 361 unlinked_leg_add(unlinked_circuits_t *unlinked, leg_t *leg) 362 { 363 tor_assert(unlinked); 364 tor_assert(leg); 365 366 smartlist_add(unlinked->legs, leg); 367 } 368 369 /** Return an unlinked leg for the given unlinked object and for the given 370 * circuit. */ 371 static inline leg_t * 372 leg_find(const unlinked_circuits_t *unlinked, const circuit_t *circ) 373 { 374 SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { 375 if (leg->circ == circ) { 376 return leg; 377 } 378 } SMARTLIST_FOREACH_END(leg); 379 return NULL; 380 } 381 382 /** Return the given circuit leg from its unlinked set (if any). */ 383 static leg_t * 384 unlinked_leg_find(const circuit_t *circ, bool is_client) 385 { 386 unlinked_circuits_t *unlinked = 387 unlinked_pool_get(circ->conflux_pending_nonce, is_client); 388 if (!unlinked) { 389 return NULL; 390 } 391 return leg_find(unlinked, circ); 392 } 393 394 static void 395 unlinked_leg_del_and_free(unlinked_circuits_t *unlinked, 396 const circuit_t *circ) 397 { 398 tor_assert(circ); 399 tor_assert(unlinked); 400 401 SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { 402 if (leg->circ == circ) { 403 SMARTLIST_DEL_CURRENT(unlinked->legs, leg); 404 leg_free(leg); 405 break; 406 } 407 } SMARTLIST_FOREACH_END(leg); 408 } 409 410 /** 411 * Ensure that the given circuit has no attached streams. 412 * 413 * This validation function is called at various stages for 414 * unlinked circuits, to make sure they have no streams. 415 */ 416 static void 417 validate_circ_has_no_streams(circuit_t *circ) 418 { 419 if (CIRCUIT_IS_ORIGIN(circ)) { 420 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); 421 if (BUG(ocirc->p_streams)) { 422 log_warn(LD_BUG, 423 "Unlinked Conflux circuit %u has attached streams.", 424 ocirc->global_identifier); 425 ocirc->p_streams = NULL; 426 } 427 if (BUG(ocirc->half_streams)) { 428 log_warn(LD_BUG, 429 "Unlinked conflux circ %u has half streams.", 430 ocirc->global_identifier); 431 ocirc->half_streams = NULL; 432 } 433 } else { 434 or_circuit_t *orcirc = TO_OR_CIRCUIT(circ); 435 if (BUG(orcirc->n_streams)) { 436 log_warn(LD_BUG, 437 "Unlinked conflux circuit has attached streams."); 438 orcirc->n_streams = NULL; 439 } 440 if (BUG(orcirc->resolving_streams)) { 441 log_warn(LD_BUG, 442 "Unlinked conflux circuit has resolving streams."); 443 orcirc->resolving_streams = NULL; 444 } 445 } 446 } 447 448 /** Return true iff the legs in the given unlinked set are valid and coherent 449 * to be a linked set. */ 450 static bool 451 validate_unlinked_legs(unlinked_circuits_t *unlinked) 452 { 453 bool valid = true; 454 uint8_t version; 455 uint8_t *nonce = NULL; 456 457 tor_assert(unlinked); 458 459 SMARTLIST_FOREACH_BEGIN(unlinked->legs, const leg_t *, leg) { 460 if (!nonce) { 461 nonce = leg->link->nonce; 462 version = leg->link->version; 463 } else { 464 /* Version and nonce must match in all legs. */ 465 valid &= (leg->link->version == version && 466 tor_memeq(leg->link->nonce, nonce, sizeof(leg->link->nonce))); 467 } 468 469 // If the other ends last sent sequence number is higher than the 470 // last sequence number we delivered, we have data loss, and cannot link. 471 if (leg->link->last_seqno_sent > unlinked->cfx->last_seq_delivered) { 472 log_fn(unlinked->is_client ? LOG_NOTICE : LOG_PROTOCOL_WARN, LD_CIRC, 473 "Data loss detected while trying to add a conflux leg."); 474 valid = false; 475 476 // TODO-329-ARTI: Instead of closing the set here, we could 477 // immediately send a SWITCH cell and re-send the missing data. 478 // To do this, though, we would need to constantly buffer at least 479 // a cwnd worth of sent data to retransmit. We're not going to try 480 // this in C-Tor, but arti could consider it. 481 } 482 validate_circ_has_no_streams(leg->circ); 483 } SMARTLIST_FOREACH_END(leg); 484 485 /* Note that if no legs, it validates. */ 486 487 return valid; 488 } 489 490 /** Add up a new leg to the given conflux object. */ 491 static void 492 cfx_add_leg(conflux_t *cfx, leg_t *leg) 493 { 494 tor_assert(cfx); 495 tor_assert(leg); 496 tor_assert(leg->link); 497 498 /* Big trouble if we add a leg to the wrong set. */ 499 tor_assert(tor_memeq(cfx->nonce, leg->link->nonce, sizeof(cfx->nonce))); 500 501 conflux_leg_t *cleg = tor_malloc_zero(sizeof(*cleg)); 502 cleg->circ = leg->circ; 503 // TODO-329-ARTI: Blindly copying the values from the cell. Is this correct? 504 // I think no... When adding new legs, switching to this leg is 505 // likely to break, unless the sender tracks what link cell it sent.. 506 // Is that the best option? Or should we use the max of our legs, here? 507 // (It seems the other side will have no idea what our current maxes 508 /// are, so this option seems better right now) 509 cleg->last_seq_recv = leg->link->last_seqno_sent; 510 cleg->last_seq_sent = leg->link->last_seqno_recv; 511 cleg->circ_rtts_usec = leg->rtt_usec; 512 cleg->linked_sent_usec = leg->link_sent_usec; 513 514 cfx->params.alg = conflux_choose_algorithm(leg->link->desired_ux); 515 516 /* Add leg to given conflux. */ 517 smartlist_add(cfx->legs, cleg); 518 519 /* Ensure the new circuit has no streams. */ 520 validate_circ_has_no_streams(leg->circ); 521 522 /* If this is not the first leg, get the first leg, and get 523 * the reference streams from it. */ 524 if (CONFLUX_NUM_LEGS(cfx) > 0) { 525 conflux_leg_t *first_leg = smartlist_get(cfx->legs, 0); 526 if (CIRCUIT_IS_ORIGIN(first_leg->circ)) { 527 origin_circuit_t *old_circ = TO_ORIGIN_CIRCUIT(first_leg->circ); 528 origin_circuit_t *new_circ = TO_ORIGIN_CIRCUIT(leg->circ); 529 530 new_circ->p_streams = old_circ->p_streams; 531 new_circ->half_streams = old_circ->half_streams; 532 /* Sync all legs with the new stream(s). */ 533 conflux_sync_circ_fields(cfx, old_circ); 534 } else { 535 or_circuit_t *old_circ = TO_OR_CIRCUIT(first_leg->circ); 536 or_circuit_t *new_circ = TO_OR_CIRCUIT(leg->circ); 537 new_circ->n_streams = old_circ->n_streams; 538 new_circ->resolving_streams = old_circ->resolving_streams; 539 } 540 } 541 542 if (CIRCUIT_IS_ORIGIN(cleg->circ)) { 543 tor_assert_nonfatal(cleg->circ->purpose == 544 CIRCUIT_PURPOSE_CONFLUX_UNLINKED); 545 circuit_change_purpose(cleg->circ, CIRCUIT_PURPOSE_CONFLUX_LINKED); 546 } 547 conflux_validate_stream_lists(cfx); 548 } 549 550 /** 551 * Clean up a circuit from its conflux_t object. 552 * 553 * Return true if closing this circuit should tear down the entire set, 554 * false otherwise. 555 */ 556 static bool 557 cfx_del_leg(conflux_t *cfx, const circuit_t *circ) 558 { 559 conflux_leg_t *leg; 560 bool full_teardown = false; 561 562 tor_assert(cfx); 563 tor_assert(circ); 564 565 leg = conflux_get_leg(cfx, circ); 566 if (!leg) { 567 goto end; 568 } 569 570 // If the circuit still has inflight data, teardown 571 const struct congestion_control_t *cc = circuit_ccontrol(circ); 572 tor_assert(cc); 573 tor_assert(cc->sendme_inc); 574 if (cc->inflight >= cc->sendme_inc) { 575 full_teardown = true; 576 log_info(LD_CIRC, "Conflux current circuit has closed with " 577 "data in flight, tearing down entire set."); 578 } 579 580 /* Remove it from the cfx. */ 581 smartlist_remove(cfx->legs, leg); 582 583 /* After removal, if this leg had the highest sent (or recv) 584 * sequence number, it was in active use by us (or the other side). 585 * We need to tear down the entire set. */ 586 // TODO-329-ARTI: If we support resumption, we don't need this. 587 if (CONFLUX_NUM_LEGS(cfx) > 0) { 588 if (conflux_get_max_seq_sent(cfx) < leg->last_seq_sent || 589 conflux_get_max_seq_recv(cfx) < leg->last_seq_recv) { 590 full_teardown = true; 591 log_info(LD_CIRC, "Conflux sequence number check failed, " 592 "tearing down entire set."); 593 } 594 } 595 596 /* Cleanup any reference to leg. */ 597 if (cfx->curr_leg == leg) { 598 cfx->curr_leg = NULL; 599 full_teardown = true; 600 log_info(LD_CIRC, "Conflux current circuit has closed, " 601 "tearing down entire set."); 602 } 603 if (cfx->prev_leg == leg) { 604 cfx->prev_leg = NULL; 605 } 606 607 tor_free(leg); 608 609 end: 610 return full_teardown; 611 } 612 613 /** Close the circuit of each legs of the given unlinked object. */ 614 static void 615 unlinked_close_all_legs(unlinked_circuits_t *unlinked) 616 { 617 smartlist_t *circ_to_close = NULL; 618 619 tor_assert(unlinked); 620 621 /* Small optimization here, avoid this work if no legs. */ 622 if (smartlist_len(unlinked->legs) == 0) { 623 return; 624 } 625 626 /* We will iterate over all legs and put the circuit in its own list and then 627 * mark them for close. The unlinked object gets freed opportunistically once 628 * there is no more legs attached to it and so we can't hold a reference 629 * while closing circuits. */ 630 circ_to_close = smartlist_new(); 631 632 SMARTLIST_FOREACH(unlinked->legs, leg_t *, leg, 633 smartlist_add(circ_to_close, leg->circ)); 634 unlinked = NULL; 635 636 /* The leg gets cleaned up in the circuit close. */ 637 SMARTLIST_FOREACH_BEGIN(circ_to_close, circuit_t *, circ) { 638 if (CIRCUIT_IS_ORIGIN(circ)) { 639 tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED); 640 } 641 if (!circ->marked_for_close) { 642 circuit_mark_for_close(circ, END_CIRC_REASON_INTERNAL); 643 } 644 } SMARTLIST_FOREACH_END(circ); 645 646 /* Drop the list and ignore its content, we don't have ownership. */ 647 smartlist_free(circ_to_close); 648 } 649 650 /** Either closee all legs of the given unlinked set or delete it from the pool 651 * and free its memory. 652 * 653 * Important: The unlinked object is freed opportunistically when legs are 654 * removed until the point none remains. And so, it is only safe to free the 655 * object if no more legs exist. 656 */ 657 static void 658 unlinked_close_or_free(unlinked_circuits_t *unlinked) 659 { 660 if (!unlinked) { 661 return; 662 } 663 664 /* If we have legs, the circuit close will trigger the unlinked object to be 665 * opportunistically freed. Else, we do it explicitly. */ 666 if (smartlist_len(unlinked->legs) > 0) { 667 unlinked_close_all_legs(unlinked); 668 } else { 669 unlinked_pool_del_and_free(unlinked, unlinked->is_client); 670 } 671 /* Either the unlinked object has been freed or the last leg close will free 672 * it so from this point on, nullify for safety reasons. */ 673 unlinked = NULL; 674 } 675 676 /** Upon an error condition or a close of an in-use circuit, we must close all 677 * linked and unlinked circuits associated with a set. When the last leg of 678 * each set is closed, the set is removed from the pool. */ 679 void 680 conflux_mark_all_for_close(const uint8_t *nonce, bool is_client, int reason) 681 { 682 /* It is possible that for a nonce we have both an unlinked set and a linked 683 * set. This happens if there is a recovery leg launched for an existing 684 * linked set. */ 685 686 /* Close the unlinked set. */ 687 unlinked_circuits_t *unlinked = unlinked_pool_get(nonce, is_client); 688 if (unlinked) { 689 unlinked_close_or_free(unlinked); 690 } 691 /* In case it gets freed, be safe here. */ 692 unlinked = NULL; 693 694 /* Close the linked set. It will free itself upon the close of 695 * the last leg. */ 696 conflux_t *linked = linked_pool_get(nonce, is_client); 697 if (linked) { 698 if (linked->in_full_teardown) { 699 return; 700 } 701 linked->in_full_teardown = true; 702 703 smartlist_t *circ_to_close = smartlist_new(); 704 705 SMARTLIST_FOREACH(linked->legs, conflux_leg_t *, leg, 706 smartlist_add(circ_to_close, leg->circ)); 707 708 SMARTLIST_FOREACH(circ_to_close, circuit_t *, circ, 709 circuit_mark_for_close(circ, reason)); 710 711 /* Drop the list and ignore its content, we don't have ownership. */ 712 smartlist_free(circ_to_close); 713 } 714 } 715 716 /** Helper: Free function taking a void pointer for the digest256map_free. */ 717 static inline void 718 free_unlinked_void_(void *ptr) 719 { 720 unlinked_circuits_t *unlinked = ptr; 721 unlinked_pool_del_and_free(unlinked, unlinked->is_client); 722 } 723 724 /** Attempt to finalize the unlinked set to become a linked set and be put in 725 * the linked pool. 726 * 727 * If this finalized successfully, the given unlinked object is freed. */ 728 static link_circ_err_t 729 try_finalize_set(unlinked_circuits_t *unlinked) 730 { 731 link_circ_err_t err = ERR_LINK_CIRC_OK; 732 bool is_client; 733 734 tor_assert(unlinked); 735 tor_assert(unlinked->legs); 736 tor_assert(unlinked->cfx); 737 tor_assert(unlinked->cfx->legs); 738 739 /* Without legs, this is not ready to become a linked set. */ 740 if (BUG(smartlist_len(unlinked->legs) == 0)) { 741 err = ERR_LINK_CIRC_MISSING_LEG; 742 goto end; 743 } 744 745 /* If there are too many legs, we can't link. */ 746 if (smartlist_len(unlinked->legs) + 747 smartlist_len(unlinked->cfx->legs) > conflux_params_get_max_legs_set()) { 748 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 749 "Conflux set has too many legs to link. " 750 "Rejecting this circuit."); 751 conflux_log_set(LOG_PROTOCOL_WARN, unlinked->cfx, unlinked->is_client); 752 err = ERR_LINK_CIRC_INVALID_LEG; 753 goto end; 754 } 755 756 /* Validate that all legs are coherent and parameters match. On failure, we 757 * teardown the whole unlinked set because this means we either have a code 758 * flow problem or the Exit is trying to trick us. */ 759 if (!validate_unlinked_legs(unlinked)) { 760 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 761 "Conflux unlinked set legs are not validating. Tearing it down."); 762 conflux_mark_all_for_close(unlinked->cfx->nonce, unlinked->is_client, 763 END_CIRC_REASON_TORPROTOCOL); 764 err = ERR_LINK_CIRC_INVALID_LEG; 765 goto end; 766 } 767 768 /* Check all linked status. All need to be true in order to finalize the set 769 * and move it to the linked pool. */ 770 SMARTLIST_FOREACH_BEGIN(unlinked->legs, const leg_t *, leg) { 771 /* We are still waiting on a leg. */ 772 if (!leg->linked) { 773 log_info(LD_CIRC, "Can't finalize conflux set, still waiting on at " 774 "least one leg to link up."); 775 776 goto end; 777 } 778 } SMARTLIST_FOREACH_END(leg); 779 780 /* Finalize the cfx object by adding all legs into it. */ 781 SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { 782 /* Removing the leg from the list is important so we avoid ending up with a 783 * leg in the unlinked list that is set with LINKED purpose. */ 784 SMARTLIST_DEL_CURRENT(unlinked->legs, leg); 785 786 /* We are ready to attach the leg to the cfx object now. */ 787 cfx_add_leg(unlinked->cfx, leg); 788 789 /* Clean the pending nonce and set the conflux object in the circuit. */ 790 leg->circ->conflux = unlinked->cfx; 791 792 /* We are done with this leg object. */ 793 leg_free(leg); 794 } SMARTLIST_FOREACH_END(leg); 795 796 is_client = unlinked->is_client; 797 798 /* Add the conflux object to the linked pool. For an existing linked cfx 799 * object, we'll simply replace it with itself. */ 800 linked_pool_add(unlinked->cfx, is_client); 801 802 /* Remove it from the unlinked pool. */ 803 unlinked_pool_del(unlinked, is_client); 804 805 /* We don't recover a leg when it is linked but if we would like to support 806 * session ressumption, this would be very important in order to allow new 807 * legs to be created/recovered. */ 808 unlinked->cfx->num_leg_launch = 0; 809 810 /* Nullify because we are about to free the unlinked object and the cfx has 811 * moved to all circuits. */ 812 unlinked->cfx = NULL; 813 unlinked_free(unlinked); 814 815 log_info(LD_CIRC, 816 "Successfully linked a conflux %s set which is now usable.", 817 is_client ? "client" : "relay"); 818 819 end: 820 return err; 821 } 822 823 /** Record the RTT for this client circuit. 824 * 825 * Return the RTT value. UINT64_MAX is returned if we couldn't find the initial 826 * measurement of when the cell was sent or if the leg is missing. */ 827 static uint64_t 828 record_rtt_client(const circuit_t *circ) 829 { 830 tor_assert(circ); 831 tor_assert(circ->conflux_pending_nonce); 832 tor_assert(CIRCUIT_IS_ORIGIN(circ)); 833 834 leg_t *leg = unlinked_leg_find(circ, true); 835 836 if (BUG(!leg || leg->link_sent_usec == 0)) { 837 log_warn(LD_BUG, 838 "Conflux: Trying to record client RTT without a timestamp"); 839 goto err; 840 } 841 842 uint64_t now = monotime_absolute_usec(); 843 tor_assert_nonfatal(now >= leg->link_sent_usec); 844 leg->rtt_usec = now - leg->link_sent_usec; 845 if (leg->rtt_usec == 0) { 846 log_warn(LD_CIRC, "Clock appears stalled for conflux."); 847 // TODO-329-TUNING: For now, let's accept this case. We need to do 848 // tuning and clean up the tests such that they use RTT in order to 849 // fail here. 850 //goto err; 851 } 852 return leg->rtt_usec; 853 854 err: 855 // Avoid using this leg until a timestamp comes in 856 if (leg) 857 leg->rtt_usec = UINT64_MAX; 858 return UINT64_MAX; 859 } 860 861 /** Record the RTT for this Exit circuit. 862 * 863 * Return the RTT value. UINT64_MAX is returned if we couldn't find the initial 864 * measurement of when the cell was sent or if the leg is missing. */ 865 866 static uint64_t 867 record_rtt_exit(const circuit_t *circ) 868 { 869 tor_assert(circ); 870 tor_assert(circ->conflux); 871 tor_assert(CIRCUIT_IS_ORCIRC(circ)); 872 873 conflux_leg_t *leg = conflux_get_leg(circ->conflux, circ); 874 875 if (BUG(!leg || leg->linked_sent_usec == 0)) { 876 log_warn(LD_BUG, 877 "Conflux: Trying to record exit RTT without a timestamp"); 878 goto err; 879 } 880 881 uint64_t now = monotime_absolute_usec(); 882 tor_assert_nonfatal(now >= leg->linked_sent_usec); 883 leg->circ_rtts_usec = now - leg->linked_sent_usec; 884 885 if (leg->circ_rtts_usec == 0) { 886 log_warn(LD_CIRC, "Clock appears stalled for conflux."); 887 goto err; 888 } 889 return leg->circ_rtts_usec; 890 891 err: 892 if (leg) 893 leg->circ_rtts_usec = UINT64_MAX; 894 return UINT64_MAX; 895 } 896 897 /** For the given circuit, record the RTT from when the LINK or LINKED cell was 898 * sent that is this function works for either client or Exit. 899 * 900 * Return false if the RTT is too high for our standard else true. */ 901 static bool 902 record_rtt(const circuit_t *circ, bool is_client) 903 { 904 uint64_t rtt_usec; 905 906 tor_assert(circ); 907 908 if (is_client) { 909 rtt_usec = record_rtt_client(circ); 910 911 if (rtt_usec == UINT64_MAX) 912 return false; 913 914 if (rtt_usec >= get_circuit_build_timeout_ms()*1000) { 915 log_info(LD_CIRC, "Conflux leg RTT is above circuit build time out " 916 "currently at %f msec. Relaunching.", 917 get_circuit_build_timeout_ms()); 918 return false; 919 } 920 } else { 921 rtt_usec = record_rtt_exit(circ); 922 } 923 924 return true; 925 } 926 927 /** Link the given circuit within its unlinked set. This is called when either 928 * the LINKED or LINKED_ACK is received depending on which side of the circuit 929 * it is. 930 * 931 * It attempts to finalize the unlinked set as well which, if successful, puts 932 * it in the linked pool. */ 933 static link_circ_err_t 934 link_circuit(circuit_t *circ) 935 { 936 link_circ_err_t err = ERR_LINK_CIRC_OK; 937 unlinked_circuits_t *unlinked = NULL; 938 bool is_client = false; 939 940 tor_assert(circ); 941 if (CIRCUIT_IS_ORIGIN(circ)) { 942 tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED); 943 is_client = true; 944 } 945 946 unlinked = unlinked_pool_get(circ->conflux_pending_nonce, is_client); 947 if (BUG(!unlinked)) { 948 log_warn(LD_BUG, "Failed to find the unlinked set %s when linking. " 949 "Closing circuit.", 950 fmt_nonce(circ->conflux_pending_nonce)); 951 err = ERR_LINK_CIRC_MISSING_SET; 952 goto end; 953 } 954 955 leg_t *leg = leg_find(unlinked, circ); 956 if (BUG(!leg)) { 957 /* Failure to find the leg when linking a circuit is an important problem 958 * so log loudly and error. */ 959 log_warn(LD_BUG, "Failed to find leg for the unlinked set %s when " 960 "linking. Closing circuit.", 961 fmt_nonce(unlinked->cfx->nonce)); 962 err = ERR_LINK_CIRC_MISSING_LEG; 963 goto end; 964 } 965 966 /* Successful link. Attempt to finalize the set in case this was the last 967 * LINKED or LINKED_ACK cell to receive. */ 968 leg->linked = true; 969 err = try_finalize_set(unlinked); 970 971 end: 972 return err; 973 } 974 975 /** Launch a brand new set. 976 * 977 * Return true if all legs successfully launched or false if one failed. */ 978 STATIC bool 979 launch_new_set(int num_legs) 980 { 981 uint8_t nonce[DIGEST256_LEN]; 982 983 /* Brand new nonce for this set. */ 984 crypto_rand((char *) nonce, sizeof(nonce)); 985 986 /* Launch all legs. */ 987 for (int i = 0; i < num_legs; i++) { 988 if (!conflux_launch_leg(nonce)) { 989 /* This function cleans up entirely the unlinked set if a leg is unable 990 * to be launched. The recovery would be complex here. */ 991 goto err; 992 } 993 } 994 995 return true; 996 997 err: 998 return false; 999 } 1000 1001 static unlinked_circuits_t * 1002 unlinked_get_or_create(const uint8_t *nonce, bool is_client) 1003 { 1004 unlinked_circuits_t *unlinked; 1005 1006 tor_assert(nonce); 1007 1008 unlinked = unlinked_pool_get(nonce, is_client); 1009 if (!unlinked) { 1010 unlinked = unlinked_new(nonce, is_client); 1011 1012 /* If this is a leg of an existing linked set, use that conflux object 1013 * instead so all legs point to the same. It is put in the leg's circuit 1014 * once the link is confirmed. */ 1015 conflux_t *cfx = linked_pool_get(nonce, is_client); 1016 if (cfx) { 1017 conflux_free(unlinked->cfx); 1018 unlinked->cfx = cfx; 1019 unlinked->is_for_linked_set = true; 1020 } 1021 /* Add this set to the unlinked pool. */ 1022 unlinked_pool_add(unlinked, is_client); 1023 } 1024 1025 return unlinked; 1026 } 1027 1028 /** 1029 * On the client side, we need to determine if there is already 1030 * an exit in use for this set, and if so, use that. 1031 * 1032 * Otherwise, we return NULL and the exit is decided by the 1033 * circuitbuild.c code. 1034 */ 1035 static extend_info_t * 1036 get_exit_for_nonce(const uint8_t *nonce) 1037 { 1038 extend_info_t *exit = NULL; 1039 1040 tor_assert(nonce); 1041 1042 // First, check the linked pool for the nonce 1043 const conflux_t *cfx = linked_pool_get(nonce, true); 1044 if (cfx) { 1045 tor_assert(cfx->legs); 1046 /* Get the exit from the first leg */ 1047 conflux_leg_t *leg = smartlist_get(cfx->legs, 0); 1048 tor_assert(leg); 1049 tor_assert(leg->circ); 1050 tor_assert(TO_ORIGIN_CIRCUIT(leg->circ)->cpath); 1051 exit = TO_ORIGIN_CIRCUIT(leg->circ)->cpath->prev->extend_info; 1052 tor_assert(exit); 1053 } else { 1054 unlinked_circuits_t *unlinked = NULL; 1055 unlinked = unlinked_pool_get(nonce, true); 1056 1057 if (unlinked) { 1058 tor_assert(unlinked->legs); 1059 if (smartlist_len(unlinked->legs) > 0) { 1060 /* Get the exit from the first leg */ 1061 leg_t *leg = smartlist_get(unlinked->legs, 0); 1062 tor_assert(leg); 1063 tor_assert(leg->circ); 1064 tor_assert(TO_ORIGIN_CIRCUIT(leg->circ)->cpath); 1065 exit = TO_ORIGIN_CIRCUIT(leg->circ)->cpath->prev->extend_info; 1066 tor_assert(exit); 1067 } 1068 } 1069 } 1070 1071 return exit; 1072 } 1073 1074 /** 1075 * Return the currently configured client UX. 1076 */ 1077 static uint8_t 1078 get_client_ux(void) 1079 { 1080 #ifdef TOR_UNIT_TESTS 1081 return DEFAULT_CLIENT_UX; 1082 #else 1083 const or_options_t *opt = get_options(); 1084 tor_assert(opt); 1085 (void)DEFAULT_CLIENT_UX; 1086 1087 /* Return the UX */ 1088 return opt->ConfluxClientUX; 1089 #endif 1090 } 1091 1092 /** Return true iff the given conflux object is allowed to launch a new leg. If 1093 * the cfx object is NULL, then it is always allowed to launch a new leg. */ 1094 static bool 1095 launch_leg_is_allowed(const conflux_t *cfx) 1096 { 1097 if (!cfx) { 1098 goto allowed; 1099 } 1100 1101 /* The maximum number of retry is the minimum number of legs we are allowed 1102 * per set plus the maximum amount of retries we are allowed to do. */ 1103 unsigned int max_num_launch = 1104 conflux_params_get_num_legs_set() + 1105 conflux_params_get_max_unlinked_leg_retry(); 1106 1107 /* Only log once per nonce if we've reached the maximum. */ 1108 if (cfx->num_leg_launch == max_num_launch) { 1109 log_info(LD_CIRC, "Maximum number of leg launch reached for nonce %s", 1110 fmt_nonce(cfx->nonce)); 1111 } 1112 1113 if (cfx->num_leg_launch >= max_num_launch) { 1114 return false; 1115 } 1116 1117 allowed: 1118 return true; 1119 } 1120 1121 /* 1122 * Public API. 1123 */ 1124 1125 /** Launch a new conflux leg for the given nonce. 1126 * 1127 * Return true on success else false which teardowns the entire unlinked set if 1128 * any. */ 1129 bool 1130 conflux_launch_leg(const uint8_t *nonce) 1131 { 1132 int flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_NEED_CAPACITY | 1133 CIRCLAUNCH_NEED_CONFLUX; 1134 unlinked_circuits_t *unlinked = NULL; 1135 extend_info_t *exit = NULL; 1136 1137 tor_assert(nonce); 1138 1139 /* Get or create a new unlinked object for this leg. */ 1140 unlinked = unlinked_get_or_create(nonce, true); 1141 tor_assert(unlinked); 1142 1143 /* If we have an existing linked set, validate the number of leg retries 1144 * before attempting the launch. */ 1145 if (!launch_leg_is_allowed(unlinked->cfx)) { 1146 goto err; 1147 } 1148 1149 exit = get_exit_for_nonce(nonce); 1150 1151 if (exit) { 1152 log_info(LD_CIRC, "Launching conflux leg for nonce %s.", fmt_nonce(nonce)); 1153 } else { 1154 log_info(LD_CIRC, "Launching new conflux set for nonce %s.", 1155 fmt_nonce(nonce)); 1156 } 1157 1158 /* Increase the retry count for this conflux object as in this nonce. 1159 * We must do this now, because some of the maze's early failure paths 1160 * call right back into this function for relaunch. */ 1161 unlinked->cfx->num_leg_launch++; 1162 1163 origin_circuit_t *circ = 1164 circuit_establish_circuit_conflux(nonce, CIRCUIT_PURPOSE_CONFLUX_UNLINKED, 1165 exit, flags); 1166 1167 /* The above call to establish a circuit can send us back a closed 1168 * circuit if the OOM handler closes this very circuit while in that 1169 * function. OOM handler runs everytime we queue a cell on a circuit which 1170 * the above function does with the CREATE cell. 1171 * 1172 * The BUG() checks after are in the same spirit which is that there are so 1173 * many things that can happen in that establish circuit function that we 1174 * ought to make sure we have a valid nonce and a valid conflux object. */ 1175 if (!circ || TO_CIRCUIT(circ)->marked_for_close) { 1176 goto err; 1177 } 1178 /* We think this won't happen but it might. The maze is powerful. #41155 */ 1179 if (BUG(!TO_CIRCUIT(circ)->conflux_pending_nonce || !unlinked->cfx)) { 1180 goto err; 1181 } 1182 1183 /* At this point, the unlinked object has either a new conflux_t or the one 1184 * used by a linked set so it is fine to use the cfx from the unlinked object 1185 * from now on. */ 1186 1187 /* Get the max_seq_sent and recv from the linked pool, if it exists, and pass 1188 * to new link cell. */ 1189 uint64_t last_seq_sent = conflux_get_max_seq_sent(unlinked->cfx); 1190 uint64_t last_seq_recv = unlinked->cfx->last_seq_delivered; 1191 1192 // TODO-329-ARTI: To support resumption/retransmit, the client should store 1193 // the last_seq_sent now, so that it can know how much data to retransmit to 1194 // the server after link. C-Tor will not be implementing this, but arti and 1195 // arti-relay could (if resumption seems worthwhile; it may not be worth the 1196 // memory storage there, either). 1197 1198 /* We have a circuit, create the new leg and attach it to the set. */ 1199 leg_t *leg = leg_new(TO_CIRCUIT(circ), 1200 conflux_cell_new_link(nonce, 1201 last_seq_sent, last_seq_recv, 1202 get_client_ux())); 1203 1204 unlinked_leg_add(unlinked, leg); 1205 return true; 1206 1207 err: 1208 return false; 1209 } 1210 1211 /** 1212 * Add the identity digest of the guard nodes of all legs of the conflux 1213 * circuit. 1214 * 1215 * This function checks both pending and linked conflux circuits. 1216 */ 1217 void 1218 conflux_add_guards_to_exclude_list(const origin_circuit_t *orig_circ, 1219 smartlist_t *excluded) 1220 { 1221 tor_assert(orig_circ); 1222 tor_assert(excluded); 1223 1224 /* Ease our lives. */ 1225 const circuit_t *circ = TO_CIRCUIT(orig_circ); 1226 1227 /* Ignore if this is not conflux related. */ 1228 if (!CIRCUIT_IS_CONFLUX(circ)) { 1229 return; 1230 } 1231 1232 /* When building a circuit, we should not have a conflux object 1233 * ourselves (though one may exist elsewhere). */ 1234 tor_assert(!circ->conflux); 1235 1236 /* Getting here without a nonce is a code flow issue. */ 1237 if (BUG(!circ->conflux_pending_nonce)) { 1238 return; 1239 } 1240 1241 /* If there is only one bridge, then only issue a warn once that 1242 * at least two bridges are best for conflux. Exempt Snowflake 1243 * from this warn */ 1244 if (get_options()->UseBridges && !conflux_can_exclude_used_bridges()) { 1245 /* Do not build any exclude lists; not enough bridges */ 1246 return; 1247 } 1248 1249 /* A linked set exists, use it. */ 1250 const conflux_t *cfx = linked_pool_get(circ->conflux_pending_nonce, true); 1251 if (cfx) { 1252 CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) { 1253 const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); 1254 smartlist_add(excluded, 1255 tor_memdup(ocirc->cpath->extend_info->identity_digest, 1256 DIGEST_LEN)); 1257 } CONFLUX_FOR_EACH_LEG_END(leg); 1258 } 1259 1260 /* An unlinked set might exist for this nonce, if so, add the second hop of 1261 * the existing legs to the exclusion list. */ 1262 unlinked_circuits_t *unlinked = 1263 unlinked_pool_get(circ->conflux_pending_nonce, true); 1264 if (unlinked) { 1265 tor_assert(unlinked->is_client); 1266 SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { 1267 /* Convert to origin circ and get cpath */ 1268 const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); 1269 smartlist_add(excluded, 1270 tor_memdup(ocirc->cpath->extend_info->identity_digest, 1271 DIGEST_LEN)); 1272 } SMARTLIST_FOREACH_END(leg); 1273 } 1274 } 1275 1276 /** 1277 * Add the identity digest of the middle nodes of all legs of the conflux 1278 * circuit. 1279 * 1280 * This function checks both pending and linked conflux circuits. 1281 * 1282 * XXX: The add guard and middle could be merged since it is the exact same 1283 * code except for the cpath position and the identity digest vs node_t in 1284 * the list. We could use an extra param indicating guard or middle. */ 1285 void 1286 conflux_add_middles_to_exclude_list(const origin_circuit_t *orig_circ, 1287 smartlist_t *excluded) 1288 { 1289 tor_assert(orig_circ); 1290 tor_assert(excluded); 1291 1292 /* Ease our lives. */ 1293 const circuit_t *circ = TO_CIRCUIT(orig_circ); 1294 1295 /* Ignore if this is not conflux related. */ 1296 if (!CIRCUIT_IS_CONFLUX(circ)) { 1297 return; 1298 } 1299 1300 /* When building a circuit, we should not have a conflux object 1301 * ourselves (though one may exist elsewhere). */ 1302 tor_assert(!circ->conflux); 1303 1304 /* Getting here without a nonce is a code flow issue. */ 1305 if (BUG(!circ->conflux_pending_nonce)) { 1306 return; 1307 } 1308 1309 /* A linked set exists, use it. */ 1310 const conflux_t *cfx = linked_pool_get(circ->conflux_pending_nonce, true); 1311 if (cfx) { 1312 CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) { 1313 const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); 1314 node_t *node = node_get_mutable_by_id( 1315 ocirc->cpath->next->extend_info->identity_digest); 1316 if (node) { 1317 smartlist_add(excluded, node); 1318 } 1319 } CONFLUX_FOR_EACH_LEG_END(leg); 1320 } 1321 1322 /* An unlinked set might exist for this nonce, if so, add the second hop of 1323 * the existing legs to the exclusion list. */ 1324 unlinked_circuits_t *unlinked = 1325 unlinked_pool_get(circ->conflux_pending_nonce, true); 1326 if (unlinked) { 1327 tor_assert(unlinked->is_client); 1328 SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { 1329 /* Convert to origin circ and get cpath */ 1330 const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(leg->circ); 1331 node_t *node = node_get_mutable_by_id( 1332 ocirc->cpath->next->extend_info->identity_digest); 1333 if (node) { 1334 smartlist_add(excluded, node); 1335 } 1336 } SMARTLIST_FOREACH_END(leg); 1337 } 1338 } 1339 1340 /** Return the number of unused client linked set. */ 1341 static int 1342 count_client_usable_sets(void) 1343 { 1344 int count = 0; 1345 1346 DIGEST256MAP_FOREACH(client_linked_pool, key, conflux_t *, cfx) { 1347 conflux_leg_t *leg = smartlist_get(cfx->legs, 0); 1348 if (BUG(!leg->circ)) { 1349 log_warn(LD_BUG, "Client conflux linked set leg without a circuit"); 1350 continue; 1351 } 1352 1353 /* The maze marks circuits used several different ways. If any of 1354 * them are marked for this leg, launch a new one. */ 1355 if (!CONST_TO_ORIGIN_CIRCUIT(leg->circ)->unusable_for_new_conns && 1356 !CONST_TO_ORIGIN_CIRCUIT(leg->circ)->isolation_values_set && 1357 !leg->circ->timestamp_dirty) { 1358 count++; 1359 } 1360 } DIGEST256MAP_FOREACH_END; 1361 1362 return count; 1363 } 1364 1365 /** Determine if we need to launch new conflux circuits for our preemptive 1366 * pool. 1367 * 1368 * This is called once a second from the mainloop from 1369 * circuit_predict_and_launch_new(). */ 1370 void 1371 conflux_predict_new(time_t now) 1372 { 1373 (void) now; 1374 1375 /* If conflux is disabled, or we have insufficient consensus exits, 1376 * don't prebuild. */ 1377 if (!conflux_is_enabled(NULL) || 1378 router_have_consensus_path() != CONSENSUS_PATH_EXIT) { 1379 return; 1380 } 1381 1382 /* Don't attempt to build a new set if we are above our allowed maximum of 1383 * linked sets. */ 1384 if (digest256map_size(client_linked_pool) >= 1385 conflux_params_get_max_linked_set()) { 1386 return; 1387 } 1388 1389 /* Count the linked and unlinked to get the total number of sets we have 1390 * (will have). */ 1391 int num_linked = count_client_usable_sets(); 1392 int num_unlinked = digest256map_size(client_unlinked_pool); 1393 int num_set = num_unlinked + num_linked; 1394 int max_prebuilt = conflux_params_get_max_prebuilt(); 1395 1396 if (num_set >= max_prebuilt) { 1397 return; 1398 } 1399 1400 log_info(LD_CIRC, "Preemptively launching new conflux circuit set(s). " 1401 "We have %d linked and %d unlinked.", 1402 num_linked, num_unlinked); 1403 1404 for (int i = 0; i < (max_prebuilt - num_set); i++) { 1405 if (!launch_new_set(conflux_params_get_num_legs_set())) { 1406 /* Failing once likely means we'll fail next attempt so stop for now and 1407 * we'll try later. */ 1408 break; 1409 } 1410 } 1411 } 1412 1413 /** Return the first circuit from the linked pool that will work with the conn. 1414 * If no such circuit exists, return NULL. */ 1415 origin_circuit_t * 1416 conflux_get_circ_for_conn(const entry_connection_t *conn, time_t now) 1417 { 1418 /* Use conn to check the exit policy of the first circuit 1419 * of each set in the linked pool. */ 1420 tor_assert(conn); 1421 1422 DIGEST256MAP_FOREACH(client_linked_pool, key, conflux_t *, cfx) { 1423 /* Get the first circuit of the set. */ 1424 conflux_leg_t *leg = smartlist_get(cfx->legs, 0); 1425 tor_assert(leg); 1426 tor_assert(leg->circ); 1427 1428 /* Bug on these but we can recover. */ 1429 if (BUG(leg->circ->purpose != CIRCUIT_PURPOSE_CONFLUX_LINKED)) { 1430 continue; 1431 } 1432 if (BUG(!CIRCUIT_IS_ORIGIN(leg->circ))) { 1433 continue; 1434 } 1435 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(leg->circ); 1436 1437 /* Make sure the connection conforms with the exit policy and the isolation 1438 * flags also allows it. */ 1439 if (!circuit_is_acceptable(ocirc, conn, 1 /* Must be open */, 1440 CIRCUIT_PURPOSE_CONFLUX_LINKED, 1441 1 /* Need uptime */, 1442 0 /* No need for internal */, now)) { 1443 continue; 1444 } 1445 1446 /* Found a circuit that works. */ 1447 return ocirc; 1448 } DIGEST256MAP_FOREACH_END; 1449 1450 return NULL; 1451 } 1452 1453 /** The given circuit is conflux pending and has closed. This deletes the leg 1454 * from the set, attempt to finalize it and relaunch a new leg. If the set is 1455 * empty after removing this leg, it is deleted. */ 1456 static void 1457 unlinked_circuit_closed(circuit_t *circ) 1458 { 1459 uint8_t nonce[DIGEST256_LEN]; 1460 unlinked_circuits_t *unlinked = NULL; 1461 bool is_client = false; 1462 1463 tor_assert(circ); 1464 tor_assert(circ->conflux_pending_nonce); 1465 1466 if (CIRCUIT_IS_ORIGIN(circ)) { 1467 tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED); 1468 is_client = true; 1469 } 1470 1471 unlinked = unlinked_pool_get(circ->conflux_pending_nonce, is_client); 1472 1473 /* This circuit is part of set that has already been removed previously freed 1474 * by another leg closing. */ 1475 if (!unlinked) { 1476 return; 1477 } 1478 1479 /* We keep the nonce here because we will try to recover if we can and the 1480 * pending nonce will get nullified early. */ 1481 memcpy(nonce, circ->conflux_pending_nonce, sizeof(nonce)); 1482 1483 log_info(LD_CIRC, "Conflux unlinked circuit with nonce %s has closed", 1484 fmt_nonce(nonce)); 1485 1486 /* Remove leg from set. */ 1487 unlinked_leg_del_and_free(unlinked, circ); 1488 /* The circuit pending nonce has been nullified at this point. */ 1489 1490 /* If no more legs, opportunistically free the unlinked set. */ 1491 if (smartlist_len(unlinked->legs) == 0) { 1492 unlinked_pool_del_and_free(unlinked, is_client); 1493 } else if (!shutting_down && !have_been_under_memory_pressure()) { 1494 /* Launch a new leg for this set to recover if we are not shutting down or 1495 * if we are not under memory pressure. We must not launch legs under 1496 * memory pressure else it can just create a feedback loop of being closed 1497 * by the OOM handler and relaunching, rinse and repeat. */ 1498 if (CIRCUIT_IS_ORIGIN(circ)) { 1499 conflux_launch_leg(nonce); 1500 } 1501 } 1502 /* After this, it might have been freed. */ 1503 unlinked = NULL; 1504 1505 /* Unlinked circuits should not have attached streams, but check 1506 * anyway, because The Maze. */ 1507 validate_circ_has_no_streams(circ); 1508 } 1509 1510 /** Update all stream pointers to point to this circuit. 1511 * This is used when a linked circuit is closed and we need to update the 1512 * streams to point to the remaining circuit 1513 */ 1514 static void 1515 linked_update_stream_backpointers(circuit_t *circ) 1516 { 1517 tor_assert(circ); 1518 tor_assert_nonfatal(circ->conflux); 1519 1520 if (CIRCUIT_IS_ORIGIN(circ)) { 1521 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); 1522 tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED); 1523 /* Iterate over stream list using next_stream pointer, until null */ 1524 for (edge_connection_t *stream = ocirc->p_streams; stream; 1525 stream = stream->next_stream) { 1526 /* Update the circuit pointer of each stream */ 1527 stream->on_circuit = circ; 1528 stream->cpath_layer = ocirc->cpath->prev; 1529 } 1530 } else { 1531 or_circuit_t *orcirc = TO_OR_CIRCUIT(circ); 1532 /* Iterate over stream list using next_stream pointer, until null */ 1533 for (edge_connection_t *stream = orcirc->n_streams; stream; 1534 stream = stream->next_stream) { 1535 /* Update the circuit pointer of each stream */ 1536 stream->on_circuit = circ; 1537 } 1538 /* Iterate over stream list using next_stream pointer, until null */ 1539 for (edge_connection_t *stream = orcirc->resolving_streams; stream; 1540 stream = stream->next_stream) { 1541 /* Update the circuit pointer of each stream */ 1542 stream->on_circuit = circ; 1543 } 1544 } 1545 } 1546 1547 /** Nullify all streams of the given circuit. */ 1548 static void 1549 linked_nullify_streams(circuit_t *circ) 1550 { 1551 tor_assert(circ); 1552 1553 if (CIRCUIT_IS_ORIGIN(circ)) { 1554 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ); 1555 ocirc->p_streams = NULL; 1556 ocirc->half_streams = NULL; 1557 } else { 1558 or_circuit_t *orcirc = TO_OR_CIRCUIT(circ); 1559 orcirc->n_streams = NULL; 1560 orcirc->resolving_streams = NULL; 1561 } 1562 } 1563 1564 /** The given circuit is already linked to a set and has been closed. Remove it 1565 * from the set and free the pool if no more legs. */ 1566 static void 1567 linked_circuit_closed(circuit_t *circ) 1568 { 1569 bool is_client = false; 1570 bool full_teardown = false; 1571 uint8_t nonce[DIGEST256_LEN] = {0}; 1572 1573 tor_assert(circ); 1574 tor_assert(circ->conflux); 1575 1576 if (CIRCUIT_IS_ORIGIN(circ)) { 1577 tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED); 1578 is_client = true; 1579 } 1580 1581 /* Unlink circuit from its conflux object. */ 1582 full_teardown = cfx_del_leg(circ->conflux, circ); 1583 1584 if (CONFLUX_NUM_LEGS(circ->conflux) == 0) { 1585 /* Last leg, remove conflux object from linked set. */ 1586 linked_pool_del(circ->conflux->nonce, is_client); 1587 } else { 1588 /* If there are other circuits, update streams backpointers and 1589 * nullify the stream lists. We do not free those streams in circuit_free_. 1590 * (They only get freed when the last circuit is freed). */ 1591 conflux_leg_t *leg = smartlist_get(circ->conflux->legs, 0); 1592 linked_update_stream_backpointers(leg->circ); 1593 linked_nullify_streams(circ); 1594 } 1595 1596 /* Keep the nonce so we can use it through out the rest of the function in 1597 * case we nullify the conflux object before. Reason is that in the case of a 1598 * full teardown, this function becomes basically recursive and so we must 1599 * nullify the conflux object of this circuit now before the recursiveness 1600 * starts leading to all legs being removed and thus not noticing if we are 1601 * the last or the first. 1602 * 1603 * Not the prettiest but that is the price to pay to live in the C-tor maze 1604 * and protected by ballrogs. */ 1605 memcpy(nonce, circ->conflux->nonce, sizeof(nonce)); 1606 1607 /* Nullify the conflux object from the circuit being closed iff we have more 1608 * legs. Reason being that the last leg needs to have the conflux object 1609 * attached to the circuit so it can be freed in conflux_circuit_free(). */ 1610 if (CONFLUX_NUM_LEGS(circ->conflux) > 0) { 1611 circ->conflux = NULL; 1612 } 1613 1614 /* If this was a teardown condition, we need to mark other circuits, 1615 * including any potential unlinked circuits, for close. 1616 * 1617 * This call is recursive in the sense that linked_circuit_closed() will end 1618 * up being called for all legs and so by the time we come back here, the 1619 * linked is likely entirely gone. Thus why this is done last. */ 1620 if (full_teardown) { 1621 conflux_mark_all_for_close(nonce, is_client, END_CIRC_REASON_FINISHED); 1622 } 1623 } 1624 1625 /** The given circuit is being freed and it is a linked leg. Clean up and free 1626 * anything that has to do with this circuit. 1627 * 1628 * After this call, the circuit should NOT be referenced anymore anywhere. */ 1629 static void 1630 linked_circuit_free(circuit_t *circ, bool is_client) 1631 { 1632 tor_assert(circ); 1633 tor_assert(circ->conflux); 1634 tor_assert(circ->conflux->legs); 1635 tor_assert(circ->conflux->ooo_q); 1636 1637 if (is_client) { 1638 tor_assert(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_LINKED); 1639 } 1640 1641 /* Circuit can be freed without being closed and so we try to delete this leg 1642 * so we can learn if this circuit is the last leg or not. */ 1643 if (cfx_del_leg(circ->conflux, circ)) { 1644 /* Check for instances of bug #40870, which we suspect happen 1645 * during exit. If any happen outside of exit, BUG and warn. */ 1646 if (!circ->conflux->in_full_teardown) { 1647 /* We should bug and warn if we're not in a shutdown process; that 1648 * means we got here somehow without a close. */ 1649 if (BUG(!shutting_down)) { 1650 log_warn(LD_BUG, 1651 "Conflux circuit %p being freed without being marked for " 1652 "full teardown via close, with shutdown state %d. " 1653 "Please report this.", circ, shutting_down); 1654 conflux_log_set(LOG_WARN, circ->conflux, is_client); 1655 } 1656 circ->conflux->in_full_teardown = true; 1657 } 1658 } 1659 1660 if (CONFLUX_NUM_LEGS(circ->conflux) > 0) { 1661 /* The last leg will free the streams but until then, we nullify to avoid 1662 * use-after-free. */ 1663 linked_nullify_streams(circ); 1664 } else { 1665 /* We are the last leg. */ 1666 1667 /* Remove from pool in case it is still lingering there else we'll end up 1668 * in a double free situation. */ 1669 linked_pool_del(circ->conflux->nonce, is_client); 1670 1671 /* If there is an unlinked circuit that was also created for this set, we 1672 * need to look for it, and tell it is no longer part of a linked set 1673 * anymore, so it can be freed properly, or can complete the link if it is 1674 * able to. Effectively, the conflux_t object lifetime is longer than 1675 * either the linked or unlinked sets by themselves. This is a situation we 1676 * could cover with handles, but so far, it is not clear they are an 1677 * obvious benefit for other cases than this one. */ 1678 unlinked_circuits_t *unlinked = 1679 unlinked_pool_get(circ->conflux->nonce, is_client); 1680 if (unlinked) { 1681 tor_assert(unlinked->is_for_linked_set); 1682 unlinked->is_for_linked_set = false; 1683 } else { 1684 /* We are the last one, clear the conflux object. If an unlinked object 1685 * has a reference to it, it won't get freed due to is_for_linked_set 1686 * flag. */ 1687 conflux_free(circ->conflux); 1688 } 1689 } 1690 } 1691 1692 /** The given circuit is being freed and it is an unlinked leg. Clean up and 1693 * free anything that has to do with this circuit. 1694 * 1695 * After this call, the circuit should NOT be referenced anymore anywhere. */ 1696 static void 1697 unlinked_circuit_free(circuit_t *circ, bool is_client) 1698 { 1699 tor_assert(circ); 1700 tor_assert(circ->conflux_pending_nonce); 1701 if (is_client) { 1702 tor_assert(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED); 1703 } 1704 1705 /* Cleanup circuit reference if a leg exists. This is possible if the circuit 1706 * was not marked for close before being freed. */ 1707 leg_t *leg = unlinked_leg_find(circ, is_client); 1708 if (leg) { 1709 leg->circ = NULL; 1710 } 1711 1712 /* Null pointers are safe here. */ 1713 tor_free(circ->conflux_pending_nonce); 1714 } 1715 1716 /** Circuit has been marked for close. */ 1717 void 1718 conflux_circuit_has_closed(circuit_t *circ) 1719 { 1720 /* The unlinked case. If an unlinked set exists, we delete the leg and then 1721 * attempt to finalize it. After that, we'll launch a new leg to recover. */ 1722 if (circ->conflux_pending_nonce) { 1723 unlinked_circuit_closed(circ); 1724 } else if (circ->conflux) { 1725 linked_circuit_closed(circ); 1726 } 1727 } 1728 1729 /** Circuit with conflux purpose just opened. */ 1730 void 1731 conflux_circuit_has_opened(origin_circuit_t *orig_circ) 1732 { 1733 circuit_t *circ = NULL; 1734 leg_t *leg = NULL; 1735 1736 tor_assert(orig_circ); 1737 1738 circ = TO_CIRCUIT(orig_circ); 1739 1740 /* Extra safety layer so we never let a circuit opens if conflux is not 1741 * enabled. */ 1742 if (!conflux_is_enabled(circ)) { 1743 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1744 static ratelim_t conflux_ratelim = RATELIM_INIT(600); 1745 log_fn_ratelim(&conflux_ratelim, LOG_NOTICE, LD_CIRC, 1746 "Conflux circuit opened without negotiating " 1747 "congestion control"); 1748 return; 1749 } 1750 1751 /* Unrelated to conflux. */ 1752 if (circ->conflux_pending_nonce == NULL) { 1753 goto end; 1754 } 1755 1756 log_info(LD_CIRC, "Conflux circuit has opened with nonce %s", 1757 fmt_nonce(circ->conflux_pending_nonce)); 1758 1759 leg = unlinked_leg_find(circ, true); 1760 if (BUG(!leg)) { 1761 log_warn(LD_CIRC, "Unable to find conflux leg in unlinked set."); 1762 goto end; 1763 } 1764 1765 /* On failure here, the circuit is closed and thus the leg and unlinked set 1766 * will be cleaned up. */ 1767 if (!conflux_cell_send_link(leg->link, orig_circ)) { 1768 goto end; 1769 } 1770 1771 /* Mark the leg on when the LINK cell is sent. Used to timeout the circuit 1772 * for a minimum RTT when getting the LINKED. */ 1773 leg->link_sent_usec = monotime_absolute_usec(); 1774 1775 end: 1776 validate_circ_has_no_streams(circ); 1777 return; 1778 } 1779 1780 /** Process a CONFLUX_LINK cell which arrived on the given circuit. */ 1781 void 1782 conflux_process_link(circuit_t *circ, const relay_msg_t *msg) 1783 { 1784 unlinked_circuits_t *unlinked = NULL; 1785 conflux_cell_link_t *link = NULL; 1786 1787 tor_assert(circ); 1788 tor_assert(msg); 1789 1790 if (!conflux_is_enabled(circ)) { 1791 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1792 goto end; 1793 } 1794 1795 /* This cell can't be received on an origin circuit because only the endpoint 1796 * creating the circuit sends it. */ 1797 if (CIRCUIT_IS_ORIGIN(circ)) { 1798 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1799 "Got a CONFLUX_LINK cell on an origin circuit. Closing circuit."); 1800 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1801 goto end; 1802 } 1803 1804 if (!conflux_validate_source_hop(circ, NULL)) { 1805 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1806 "Got a CONFLUX_LINK with further hops. Closing circuit."); 1807 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1808 goto end; 1809 } 1810 1811 if (circ->conflux_pending_nonce) { 1812 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1813 "Got a CONFLUX_LINK on a circuit with a pending nonce. " 1814 "Closing circuit."); 1815 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1816 goto end; 1817 } 1818 1819 if (circ->conflux) { 1820 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1821 "Got a CONFLUX_LINK on an already linked circuit " 1822 "Closing circuit."); 1823 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1824 goto end; 1825 } 1826 1827 /* On errors, logging is emitted in this parsing function. */ 1828 link = conflux_cell_parse_link(msg); 1829 if (!link) { 1830 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, "Unable to parse " 1831 "CONFLUX_LINK cell. Closing circuit."); 1832 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1833 goto end; 1834 } 1835 1836 log_info(LD_CIRC, "Processing a CONFLUX_LINK for set %s", 1837 fmt_nonce(link->nonce)); 1838 1839 /* Consider this circuit a new leg. We'll now attempt to attach it to an 1840 * existing set or unlinked one. */ 1841 leg_t *leg = leg_new(circ, link); 1842 unlinked = unlinked_get_or_create(link->nonce, false); 1843 tor_assert(unlinked); 1844 1845 /* Attach leg to the unlinked set. */ 1846 unlinked_leg_add(unlinked, leg); 1847 1848 /* Set the circuit in a pending conflux state for the LINKED_ACK. */ 1849 circ->conflux_pending_nonce = tor_memdup(leg->link->nonce, 1850 sizeof(leg->link->nonce)); 1851 1852 /* Mark when we send the LINKED. */ 1853 leg->link_sent_usec = monotime_absolute_usec(); 1854 1855 /* Send LINKED. */ 1856 uint64_t last_seq_sent = conflux_get_max_seq_sent(unlinked->cfx); 1857 uint64_t last_seq_recv = unlinked->cfx->last_seq_delivered; 1858 1859 // TODO-329-ARTI: To support resumption/retransmit, the server should 1860 // store the last_seq_sent now, so that it can know how much data 1861 // to retransmit to the server after link. C-Tor will not be implementing 1862 // this, but arti and arti-relay could (if resumption seems worthwhile; 1863 // it may not be worth the memory storage there, either). 1864 1865 uint8_t nonce[DIGEST256_LEN]; 1866 memcpy(nonce, circ->conflux_pending_nonce, sizeof(nonce)); 1867 1868 /* Link the circuit to the a conflux set immediately before the LINKED is 1869 * sent. Reason is that once the client sends the LINKED_ACK, there is a race 1870 * with the BEGIN cell that can be sent immediately after and arrive first. 1871 * And so, we need to sync the streams before that happens that is before we 1872 * receive the LINKED_ACK. */ 1873 if (link_circuit(circ) != ERR_LINK_CIRC_OK) { 1874 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1875 goto end; 1876 } 1877 1878 /* Exits should always request min latency from clients */ 1879 conflux_cell_link_t *linked = conflux_cell_new_link(nonce, last_seq_sent, 1880 last_seq_recv, 1881 DEFAULT_EXIT_UX); 1882 1883 conflux_cell_send_linked(linked, TO_OR_CIRCUIT(circ)); 1884 tor_free(linked); 1885 1886 end: 1887 return; 1888 } 1889 1890 /** Process a CONFLUX_LINKED cell which arrived on the given circuit. */ 1891 void 1892 conflux_process_linked(circuit_t *circ, crypt_path_t *layer_hint, 1893 const relay_msg_t *msg) 1894 { 1895 conflux_cell_link_t *link = NULL; 1896 1897 tor_assert(circ); 1898 1899 /* 1900 * There several ways a malicious exit could create problems when sending 1901 * back this LINKED cell. 1902 * 1903 * 1. Using a different nonce that it knows about from another set. Accepting 1904 * it would mean a confirmation attack of linking sets to the same client. 1905 * To address that, the cell nonce MUST be matched with the circuit nonce. 1906 * 1907 * 2. Re-Sending a LINKED cell on an already linked circuit could create side 1908 * channel attacks or unpredictable issues. Circuit is closed. 1909 * 1910 * 3. Receiving a LINKED cell on a circuit that was not expecting it. Again, 1911 * as (2), can create side channel(s). Circuit is closed. 1912 * 1913 * 4. Receiving a LINKED cell from the another hop other than the last one 1914 * (exit). Same as (2) and (3) in terms of issues. Circuit is closed. 1915 */ 1916 1917 if (!conflux_is_enabled(circ)) { 1918 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 1919 goto end; 1920 } 1921 1922 /* LINKED cell are in response to a LINK cell which are only sent on an 1923 * origin circuit and thus received on such.*/ 1924 if (!CIRCUIT_IS_ORIGIN(circ)) { 1925 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1926 "Received CONFLUX_LINKED cell on a non origin circuit."); 1927 goto close; 1928 } 1929 1930 if (!circ->conflux_pending_nonce) { 1931 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1932 "Received a CONFLUX_LINKED cell without having sent a " 1933 "CONFLUX_LINK cell. Closing circuit."); 1934 goto close; 1935 } 1936 1937 if (circ->conflux) { 1938 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1939 "Received a CONFLUX_LINKED cell on a circuit that is already " 1940 "linked. Closing circuit."); 1941 goto close; 1942 } 1943 1944 if (!conflux_validate_source_hop(circ, layer_hint)) { 1945 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1946 "Got a CONFLUX_LINKED from wrong hop on circuit. Closing circuit."); 1947 goto close; 1948 } 1949 1950 tor_assert_nonfatal(circ->purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED); 1951 1952 /* On errors, logging is emitted in this parsing function. */ 1953 link = conflux_cell_parse_link(msg); 1954 if (!link) { 1955 goto close; 1956 } 1957 1958 log_info(LD_CIRC, "Processing a CONFLUX_LINKED for set %s", 1959 fmt_nonce(link->nonce)); 1960 1961 /* Make sure the cell nonce matches the one on the circuit that was 1962 * previously set by the CONFLUX_LINK cell. */ 1963 if (tor_memneq(link->nonce, circ->conflux_pending_nonce, 1964 sizeof(*link->nonce))) { 1965 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 1966 "Received CONFLUX_LINKED but circuit nonce doesn't match " 1967 "cell nonce. Closing circuit."); 1968 goto close; 1969 } 1970 1971 /* Find the leg from the associated unlinked set. */ 1972 leg_t *leg = unlinked_leg_find(circ, true); 1973 if (BUG(!leg)) { 1974 log_warn(LD_CIRC, "Received CONFLUX_LINKED but can't find " 1975 "associated leg. Closing circuit."); 1976 goto close; 1977 } 1978 1979 log_info(LD_CIRC, "Successfully processed a CONFLUX_LINKED cell."); 1980 1981 /* Free the old link, and store the new one. We need to validate 1982 * the one we get during finalize, not the one we sent. */ 1983 tor_free(leg->link); 1984 leg->link = link; 1985 1986 /* Record the RTT for this circuit. On failure, it means the RTT was too 1987 * high, we relaunch to recover. */ 1988 if (!record_rtt(circ, true)) { 1989 goto close; 1990 } 1991 1992 /* The following will link the circuit with its set and attempt to finalize 1993 * the set if all expected legs have linked. On error, we close the circuit 1994 * because it means the unlinked set needs to be teardowned. */ 1995 link_circ_err_t err = link_circuit(circ); 1996 switch (err) { 1997 case ERR_LINK_CIRC_OK: 1998 /* Successfully linked. */ 1999 break; 2000 case ERR_LINK_CIRC_INVALID_LEG: 2001 case ERR_LINK_CIRC_MISSING_SET: 2002 /* No relaunch if the leg is invalid or the set is not found as in the 2003 * nonce is unknown. */ 2004 break; 2005 case ERR_LINK_CIRC_BAD_RTT: 2006 case ERR_LINK_CIRC_MISSING_LEG: 2007 goto close; 2008 } 2009 2010 /* We can send the ack only if we finalize. This will not cause issues, 2011 * because LINKED_ACK is exempted from multiplexing in 2012 * conflux_should_multiplex(). */ 2013 if (!conflux_cell_send_linked_ack(TO_ORIGIN_CIRCUIT(circ))) { 2014 /* On failure, the circuit is closed by the underlying function(s). */ 2015 goto end; 2016 } 2017 2018 /* If this set is ready to use with a valid conflux set, try any pending 2019 * streams again. */ 2020 if (circ->conflux) { 2021 connection_ap_attach_pending(1); 2022 } 2023 2024 /* This cell is now considered valid for clients. */ 2025 circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), msg->length); 2026 2027 goto end; 2028 2029 close: 2030 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 2031 2032 end: 2033 return; 2034 } 2035 2036 /** Process a CONFLUX_LINKED_ACK cell which arrived on the given circuit. */ 2037 void 2038 conflux_process_linked_ack(circuit_t *circ) 2039 { 2040 tor_assert(circ); 2041 2042 if (!conflux_is_enabled(circ)) { 2043 goto close; 2044 } 2045 2046 if (CIRCUIT_IS_ORIGIN(circ)) { 2047 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 2048 "Received CONFLUX_LINKED_ACK cell on an origin circuit. Closing."); 2049 goto close; 2050 } 2051 2052 if (!conflux_validate_source_hop(circ, NULL)) { 2053 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 2054 "Got a CONFLUX_LINKED_ACK with further hops. Closing circuit."); 2055 goto close; 2056 } 2057 2058 if (BUG(!circ->conflux)) { 2059 log_fn(LOG_PROTOCOL_WARN, LD_CIRC, 2060 "Received a CONFLUX_LINKED_ACK cell on a circuit that is not" 2061 "linked. Closing circuit."); 2062 goto close; 2063 } 2064 2065 log_info(LD_CIRC, "Processing a CONFLUX_LINKED_ACK for set %s", 2066 fmt_nonce(circ->conflux->nonce)); 2067 2068 /* Record the RTT for this circuit. This should not fail */ 2069 if (BUG(!record_rtt(circ, false))) { 2070 goto close; 2071 } 2072 2073 return; 2074 2075 close: 2076 circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL); 2077 } 2078 2079 /** Called when a circuit is freed. 2080 * 2081 * It is possible a conflux circuit gets freed without being closed (for 2082 * instance SIGTERM) and so this callback is needed in order to finalize the 2083 * cleanup. */ 2084 void 2085 conflux_circuit_about_to_free(circuit_t *circ) 2086 { 2087 tor_assert(circ); 2088 2089 bool is_client = CIRCUIT_IS_ORIGIN(circ); 2090 2091 if (circ->conflux) { 2092 linked_circuit_free(circ, is_client); 2093 } else if (circ->conflux_pending_nonce) { 2094 unlinked_circuit_free(circ, is_client); 2095 } 2096 2097 /* Whatever happens, nullify all conflux related pointers. */ 2098 circ->conflux = NULL; 2099 circ->conflux_pending_nonce = NULL; 2100 } 2101 2102 /** Initialize the conflux pool subsystem. This is called by the subsys 2103 * manager. */ 2104 void 2105 conflux_pool_init(void) 2106 { 2107 if (!client_linked_pool) { 2108 client_linked_pool = digest256map_new(); 2109 } 2110 if (!client_unlinked_pool) { 2111 client_unlinked_pool = digest256map_new(); 2112 } 2113 if (!server_linked_pool) { 2114 server_linked_pool = digest256map_new(); 2115 } 2116 if (!server_unlinked_pool) { 2117 server_unlinked_pool = digest256map_new(); 2118 } 2119 } 2120 2121 /** 2122 * Return a description of all linked and unlinked circuits associated 2123 * with a conflux set. 2124 * 2125 * For use in rare bug cases that are hard to diagnose. 2126 */ 2127 void 2128 conflux_log_set(int loglevel, const conflux_t *cfx, bool is_client) 2129 { 2130 /* This could be called on a closed circuit. */ 2131 if (cfx == NULL) { 2132 return; 2133 } 2134 2135 log_fn(loglevel, 2136 LD_BUG, 2137 "Conflux %s: %d linked, %d launched. Delivered: %"PRIu64"; " 2138 "teardown: %d; Current: %p, Previous: %p", 2139 fmt_nonce(cfx->nonce), smartlist_len(cfx->legs), 2140 cfx->num_leg_launch, 2141 cfx->last_seq_delivered, cfx->in_full_teardown, 2142 cfx->curr_leg, cfx->prev_leg); 2143 2144 // Log all linked legs 2145 int legs = 0; 2146 CONFLUX_FOR_EACH_LEG_BEGIN(cfx, leg) { 2147 const struct congestion_control_t *cc = circuit_ccontrol(leg->circ); 2148 log_fn(loglevel, LD_BUG, 2149 " - Linked Leg %d purpose=%d; RTT %"PRIu64", sent: %"PRIu64 2150 "; sent: %"PRIu64", recv: %"PRIu64", infl: %"PRIu64", " 2151 "ptr: %p, idx: %d, marked: %d", 2152 legs, leg->circ->purpose, leg->circ_rtts_usec, 2153 leg->linked_sent_usec, leg->last_seq_recv, 2154 leg->last_seq_sent, cc->inflight, leg->circ, 2155 leg->circ->global_circuitlist_idx, 2156 leg->circ->marked_for_close); 2157 legs++; 2158 } CONFLUX_FOR_EACH_LEG_END(leg); 2159 2160 // Look up the nonce to see if we have any unlinked circuits. 2161 unlinked_circuits_t *unlinked = unlinked_pool_get(cfx->nonce, is_client); 2162 if (unlinked) { 2163 // Log the number of legs and the is_for_linked_set status 2164 log_fn(loglevel, LD_BUG, " - Unlinked set: %d legs, for link: %d", 2165 smartlist_len(unlinked->legs), unlinked->is_for_linked_set); 2166 legs = 0; 2167 SMARTLIST_FOREACH_BEGIN(unlinked->legs, leg_t *, leg) { 2168 log_fn(loglevel, LD_BUG, 2169 " Unlinked Leg: %d purpose=%d; linked: %d, RTT %"PRIu64", " 2170 "sent: %"PRIu64" link ptr %p, circ ptr: %p, idx: %d, marked: %d", 2171 legs, leg->circ->purpose, leg->linked, 2172 leg->rtt_usec, leg->link_sent_usec, 2173 leg->link, leg->circ, 2174 leg->circ->global_circuitlist_idx, 2175 leg->circ->marked_for_close); 2176 legs++; 2177 } SMARTLIST_FOREACH_END(leg); 2178 } 2179 } 2180 2181 /** 2182 * Conflux needs a notification when tor_shutdown() begins, so that 2183 * when circuits are freed, new legs are not launched. 2184 * 2185 * This needs a separate notification from conflux_pool_free_all(), 2186 * because circuits must be freed before that function. 2187 */ 2188 void 2189 conflux_notify_shutdown(void) 2190 { 2191 shutting_down = true; 2192 } 2193 2194 #ifdef TOR_UNIT_TESTS 2195 /** 2196 * For unit tests: Clear the shutting down state so we resume building legs. 2197 */ 2198 void 2199 conflux_clear_shutdown(void) 2200 { 2201 shutting_down = false; 2202 } 2203 #endif 2204 2205 /** Free and clean up the conflux pool subsystem. This is called by the subsys 2206 * manager AFTER all circuits have been freed which implies that all objects in 2207 * the pools aren't referenced anymore. */ 2208 void 2209 conflux_pool_free_all(void) 2210 { 2211 digest256map_free(client_linked_pool, free_conflux_void_); 2212 digest256map_free(server_linked_pool, free_conflux_void_); 2213 digest256map_free(client_unlinked_pool, free_unlinked_void_); 2214 digest256map_free(server_unlinked_pool, free_unlinked_void_); 2215 }