but those could probably be refactored or just turned into a more brute force walk over the forward list, if we needed.
Though, check out this use in circuit_package_relay_cell() where it is honestly more convenient to be able to walk backwards on the list:
thishop = layer_hint; /* moving from farthest to nearest hop */ do { tor_assert(thishop); log_debug(LD_OR,"crypting a layer of the relay cell."); if (relay_crypt_one_payload(thishop->f_crypto, cell->payload, 1) < 0) { return -1; } thishop = thishop->prev; } while (thishop != TO_ORIGIN_CIRCUIT(circ)->cpath->prev);
Sounds like a double-linked list might work there then.
If we're ok walking to the end of the list each time we need to interact with the end (which is a big part of what we do with cpaths), sure.
(To be clear, I think the difference between a doubly-linked list and a circular list is that the doubly-linked list ends, and begins, whereas the circular list has a link from the tail to the head, and from the head to the tail? Just to make sure we're using the same terms. :)