aboutsummaryrefslogtreecommitdiff
path: root/crates/tor-proto/src/channel
diff options
context:
space:
mode:
Diffstat (limited to 'crates/tor-proto/src/channel')
-rw-r--r--crates/tor-proto/src/channel/circmap.rs18
-rw-r--r--crates/tor-proto/src/channel/reactor.rs7
-rw-r--r--crates/tor-proto/src/channel/test_utils.rs1
3 files changed, 26 insertions, 0 deletions
diff --git a/crates/tor-proto/src/channel/circmap.rs b/crates/tor-proto/src/channel/circmap.rs
index 496b8aee0..1e585bf51 100644
--- a/crates/tor-proto/src/channel/circmap.rs
+++ b/crates/tor-proto/src/channel/circmap.rs
@@ -269,6 +269,24 @@ impl CircMap {
})
}
+ /// Returns `true` if the circuit with the specified `id`
+ /// is open or opening.
+ ///
+ /// Returns `false` if the circuit is not in the circuit map,
+ /// or if we have already sent a DESTROY on it.
+ pub(super) fn is_open(&self, id: CircId) -> bool {
+ let Some(entry) = self.m.get(&id) else {
+ return false;
+ };
+
+ match entry {
+ CircEnt::Opening { .. } | CircEnt::OpenOrigin { .. } => true,
+ #[cfg(feature = "relay")]
+ CircEnt::OpenRelay { .. } => true,
+ CircEnt::DestroySent(..) => false,
+ }
+ }
+
/// Inform the relevant circuit's padding subsystem that a given cell has been flushed.
pub(super) fn note_cell_flushed(&mut self, id: CircId, info: QueuedCellPaddingInfo) {
let padding_ctrl = match self.m.get(&id) {
diff --git a/crates/tor-proto/src/channel/reactor.rs b/crates/tor-proto/src/channel/reactor.rs
index 2e8dd2837..98e1859aa 100644
--- a/crates/tor-proto/src/channel/reactor.rs
+++ b/crates/tor-proto/src/channel/reactor.rs
@@ -846,7 +846,14 @@ impl<R: Runtime> Reactor<R> {
/// Called when a circuit goes away: sends a DESTROY cell and removes
/// the circuit.
+ ///
+ /// No-op if the circuit has already gone away,
+ /// (for example if we have already received DESTROY).
async fn outbound_destroy_circ(&mut self, id: CircId) -> Result<()> {
+ if !self.circs.is_open(id) {
+ return Ok(());
+ }
+
trace!(channel_id = %self, "Circuit {} is gone; sending DESTROY", id);
// Remove the circuit's entry from the map: nothing more
// can be done with it.
diff --git a/crates/tor-proto/src/channel/test_utils.rs b/crates/tor-proto/src/channel/test_utils.rs
index 9e2db0d9b..b107a53c8 100644
--- a/crates/tor-proto/src/channel/test_utils.rs
+++ b/crates/tor-proto/src/channel/test_utils.rs
@@ -314,6 +314,7 @@ impl ConnInspector {
}
/// Wait for the next message sent by the relay.
+ #[expect(dead_code)]
pub(crate) async fn relay_cell(&mut self) -> Option<AnyChanCell> {
self.relay_inspector_rx.recv().await.ok()
}