Expand description
Types to support memory quota tracking
We make these newtypes because we otherwise have a confusing a maze of
identical-looking, but supposedly semantically different, [Account
]s.
§Memory tracking architecture in Arti
§Queues
The following queues in Arti participate in the memory quota system:
- Tor streams (
StreamAccount
)- inbound data, on its way from the circuit to the stream’s user
- outbound data, on its way from the stream’s user to the circuit
- Tor circuits (
CircuitAccount
)- inbound stream requests, on their way from the circuit to the handling code
- inbound data, on its way from the channel
- Tor channels (
ChannelAccount
)- outbound data, on its way from a circuit to the channel (this ought to be accounted to the circuit, TODO #1652)
The following data buffers do not participate:
-
Our TLS implementation(s) may have internal buffers. We hope that these buffers will be kept reasonably small, and hooking into them would in any case going be quite hard.
-
TCP sockets will also buffer data, in the operating system. Hooking into this is not trivial.
-
Our pluggable transport driver can buffer some data. This should be kept to a minimum for several reasons, so we hope that the buffers are small.
-
The actual pluggable transport might buffer data. Again, this should be kept to a minimum.
§Overview
See the [tor_memquota] crate-level docs for an overview of the memquota system. To summarise:
When too much memory is in use, the queue with the oldest data is selected for reclaim. The whole Account relating to the victim queue is torn down. When the victim Account collapses, all its queues collapse too: reading ends give EOF, and writing ends give errors. This will tear down the associated Tor protocol association.
All the children Accounts of the victim Account are torn down too. This propagates the collapse to dependent Tor protocol associations.
§Accounting
Within Arti we maintain a hierarchy of [Account
]s.
These are wrapped in newtypes, here in tor_proto::memquota
.
-
ToplevelAccount
: In a single Arti instance there will be one of these, used for all memory tracking. This is held (shared) by the chanmgr and the circmgr. Unlike the other layer-specific accounts, this is just a type alias for [MemoryQuotaTracker
]. It doesn’t support claiming memory directly from it, so it won’t be subject to reclaim. -
ChannelAccount
. Contains (via parentage) everything that goes via a particular Channel. This includes all circuits on the channel, and those circuits’ streams. -
CircuitAccount
. Has theChannelAccount
as its parent. So if a queue accounted to a channel is selected for reclaim, that channel, and all of its circuits, will collapse. -
StreamAccount
. Has theCircuitAccount
as its parent. So if a queue accounted to a circuit is selected for reclaim, that circuit, and all of its streams, will collapse. If a stream’s queue is selected for reclaim, only that stream will collapse. (See #1661 for discussion of this behaviour.)
Thus, killing a single queue will reclaim the memory associated with several other queues.
Structs§
- Channel
Account - [
Account
] for a Tor Channel - Circuit
Account - [
Account
] for a Tor Circuit - Stream
Account - [
Account
] for a Tor Stream
Traits§
- Specific
Account - An [
Account
], whose type indicates which layer of the stack it’s for
Type Aliases§
- Toplevel
Account - Account for the whole system