summaryrefslogtreecommitdiff
path: root/src/or/circuitlist.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-10-02 15:11:34 -0400
committerNick Mathewson <nickm@torproject.org>2015-01-14 11:31:12 -0500
commitfb5ebfb50770062c77534d4db4c6a9c5ad475fa0 (patch)
tree52949fe80a637906c13a1f095306a9f1849692e8 /src/or/circuitlist.c
parent6c9c54e7fa8841e3c4d4d24f5933d433171d1112 (diff)
downloadtor-fb5ebfb50770062c77534d4db4c6a9c5ad475fa0.tar.gz
tor-fb5ebfb50770062c77534d4db4c6a9c5ad475fa0.zip
Avoid chan/circ linear lookups for requests
The solution I took is to not free a circuit with a pending uncancellable work item, but rather to set its magic number to a sentinel value. When we get a work item, we check whether the circuit has that magic sentinel, and if so, we free it rather than processing the reply.
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r--src/or/circuitlist.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 36ba3bffb7..d964e66922 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -745,6 +745,7 @@ circuit_free(circuit_t *circ)
{
void *mem;
size_t memlen;
+ int should_free = 1;
if (!circ)
return;
@@ -784,6 +785,8 @@ circuit_free(circuit_t *circ)
memlen = sizeof(or_circuit_t);
tor_assert(circ->magic == OR_CIRCUIT_MAGIC);
+ should_free = (ocirc->workqueue_entry == NULL);
+
crypto_cipher_free(ocirc->p_crypto);
crypto_digest_free(ocirc->p_digest);
crypto_cipher_free(ocirc->n_crypto);
@@ -826,8 +829,18 @@ circuit_free(circuit_t *circ)
* "active" checks will be violated. */
cell_queue_clear(&circ->n_chan_cells);
- memwipe(mem, 0xAA, memlen); /* poison memory */
- tor_free(mem);
+ if (should_free) {
+ memwipe(mem, 0xAA, memlen); /* poison memory */
+ tor_free(mem);
+ } else {
+ /* If we made it here, this is an or_circuit_t that still has a pending
+ * cpuworker request which we weren't able to cancel. Instead, set up
+ * the magic value so that when the reply comes back, we'll know to discard
+ * the reply and free this structure.
+ */
+ memwipe(mem, 0xAA, memlen);
+ circ->magic = DEAD_CIRCUIT_MAGIC;
+ }
}
/** Deallocate the linked list circ-><b>cpath</b>, and remove the cpath from