Pier Angelo Vendrame pushed to branch tor-browser-153.1.0esr-16.0-1 at The Tor Project / Applications / Tor Browser Commits: 6407d484 by Elena at 2026-08-19T19:37:53+02:00 fixup! TB 44806: Implement the tor integration in Rust. TB 44930: Implement the commands on the Rust control port Add a way to add a handler for when connections are closed. - - - - - 6 changed files: - toolkit/components/tor-integration/test/xpcshell/head.js - toolkit/components/tor-integration/test/xpcshell/test_control_port.js - toolkit/components/tor-integration/torITorService.idl - toolkit/components/tor-integration/tor_provider/src/ctor/control_port/control_port.rs - toolkit/components/tor-integration/tor_service/src/control_port.rs - toolkit/components/tor-launcher/TorControlPort.sys.mjs Changes: ===================================== toolkit/components/tor-integration/test/xpcshell/head.js ===================================== @@ -190,10 +190,7 @@ class ControlPortClient { } else { throw new Error("Unknown server protocol"); } - const receiver = { - onAsyncMessage: message => this.onAsyncMessage(message), - }; - this.#controlPort.start(receiver); + this.#controlPort.start(this); } sendCommand(command) { @@ -216,4 +213,6 @@ class ControlPortClient { onAsyncMessage(_message) { Assert.ok(false, "This test does not use async notifications."); } + + onClosed() {} } ===================================== toolkit/components/tor-integration/test/xpcshell/test_control_port.js ===================================== @@ -67,18 +67,27 @@ add_task(async function test_invalidSyntax() { class ControlPortClientAsyncNotification extends ControlPortClient { notificationPromise; #resolve; + closedPromise; + #closedResolve; constructor(server) { super(server); - const { promise, resolve } = Promise.withResolvers(); - this.notificationPromise = promise; - this.#resolve = resolve; + this.notificationPromise = new Promise( + resolve => (this.#resolve = resolve) + ); + this.closedPromise = new Promise( + resolve => (this.#closedResolve = resolve) + ); } onAsyncMessage(message) { Assert.equal(message, "650-Test\r\n650 notification"); this.#resolve(); } + + onClosed() { + this.#closedResolve(); + } } add_task(async function test_asyncNotification() { @@ -91,6 +100,7 @@ add_task(async function test_asyncNotification() { await cp.notificationPromise; cp.close(); server.close(); + await cp.closedPromise; }); }); ===================================== toolkit/components/tor-integration/torITorService.idl ===================================== @@ -8,6 +8,7 @@ [scriptable, uuid(4b250614-968a-412f-9191-9ffd9d4bd001)] interface torITorControlPortReceiver : nsISupports { void onAsyncMessage(in ACString message); + void onClosed(); }; [scriptable, uuid(1389d157-4695-43a2-a7d8-538aaa350766)] ===================================== toolkit/components/tor-integration/tor_provider/src/ctor/control_port/control_port.rs ===================================== @@ -5,7 +5,7 @@ use bytes::Bytes; use std::{ - cell::Cell, + cell::{Cell, RefCell}, rc::{Rc, Weak}, }; @@ -25,6 +25,7 @@ struct ControlPortInner { socket: Rc<dyn ControlSocket>, writer: Rc<CommandWriter>, message_pump: Rc<MessagePump>, + close_handler: RefCell<Option<Box<dyn FnOnce()>>>, closed: Cell<bool>, } @@ -41,6 +42,7 @@ impl ControlPortInner { Self::make_data_cb(weak_self.clone()), Self::make_async_failure_cb(weak_self.clone()), ), + close_handler: RefCell::new(None), closed: Cell::new(false), }); cp.message_pump.start().inspect_err(|_| { @@ -140,7 +142,22 @@ impl ControlPortInner { } self.reply_dispatcher.fail_all(ReplyError::ConnectionClosed); self.reply_dispatcher.set_async_handler(None); - self.socket.close() + let res = self.socket.close(); + let handler = self.close_handler.borrow_mut().take(); + if let Some(h) = handler { + h(); + } + res + } + + fn set_close_handler(&self, cb: Box<dyn FnOnce()>) { + if self.closed.get() { + // This should never happen in reality, but let's just call the + // callback if it does to make sure the callback is always called. + cb(); + return; + } + *self.close_handler.borrow_mut() = Some(cb); } } @@ -183,4 +200,9 @@ impl ControlPort { pub fn close(&self) -> Result<(), ControlSocketError> { self.0.close() } + + #[inline] + pub fn set_close_handler(&self, cb: Box<dyn FnOnce()>) { + self.0.set_close_handler(cb); + } } ===================================== toolkit/components/tor-integration/tor_service/src/control_port.rs ===================================== @@ -37,6 +37,7 @@ impl ControlPortXpcom { xpcom_method!(start => Start(receiver: *const torITorControlPortReceiver)); pub fn start(&self, receiver: &torITorControlPortReceiver) -> Result<(), nsresult> { let receiver = RefPtr::new(receiver); + let receiver2 = receiver.clone(); self.control_port .set_async_handler(Some(Box::new(move |reply| { let mut buf = Vec::new(); @@ -58,6 +59,11 @@ impl ControlPortXpcom { // pass nsCStrings created in Rust to C++. unsafe { receiver.OnAsyncMessage(&*as_str) }; }))); + self.control_port.set_close_handler(Box::new(move || { + // Safety: call to an XPCOM method of our interface that we crafted + // to make sure it was exposed on Rust bindings. + unsafe { receiver2.OnClosed() }; + })); Ok(()) } ===================================== toolkit/components/tor-launcher/TorControlPort.sys.mjs ===================================== @@ -565,6 +565,9 @@ export class TorController { onAsyncMessage(message) { self.#handleNotification(message); }, + onClosed() { + self.onClosed(); + }, }; this.#socket.start(receiver); return; View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/6407d484... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/6407d484... You're receiving this email because of your account on gitlab.torproject.org. Manage all notifications: https://gitlab.torproject.org/-/profile/notifications | Help: https://gitlab.torproject.org/help
participants (1)
-
Pier Angelo Vendrame (@pierov)