Skip to main content

dbus_router/
router.rs

1//! Router core: listen for connections and spawn sessions
2
3use crate::config::Config;
4use crate::session::Session;
5use anyhow::Result;
6use std::path::PathBuf;
7use std::sync::Arc;
8use tokio::net::UnixListener;
9
10/// The main router that listens for client connections.
11pub struct Router {
12    /// Path to the Unix socket to listen on
13    listen_path: PathBuf,
14    /// Host session bus address
15    host_addr: String,
16    /// Sandbox session bus address (default target)
17    sandbox_addr: String,
18    /// Routing configuration
19    config: Arc<Config>,
20}
21
22impl Router {
23    /// Create a new router.
24    pub fn new(
25        listen_path: PathBuf,
26        host_addr: String,
27        sandbox_addr: String,
28        config: Config,
29    ) -> Self {
30        Self {
31            listen_path,
32            host_addr,
33            sandbox_addr,
34            config: Arc::new(config),
35        }
36    }
37
38    /// Run the router, accepting connections and spawning sessions.
39    pub async fn run(&self) -> Result<()> {
40        // Remove existing socket if present
41        if self.listen_path.exists() {
42            std::fs::remove_file(&self.listen_path)?;
43        }
44
45        let listener = UnixListener::bind(&self.listen_path)?;
46        tracing::info!(path = %self.listen_path.display(), "Listening for connections");
47
48        loop {
49            match listener.accept().await {
50                Ok((stream, _addr)) => {
51                    tracing::info!("New client connection");
52
53                    let host_addr = self.host_addr.clone();
54                    let sandbox_addr = self.sandbox_addr.clone();
55                    let config = Arc::clone(&self.config);
56
57                    tokio::spawn(async move {
58                        match Session::new(stream, &host_addr, &sandbox_addr, config).await {
59                            Ok(session) => {
60                                if let Err(e) = session.run().await {
61                                    tracing::error!(error = %e, "Session error");
62                                }
63                            }
64                            Err(e) => {
65                                tracing::error!(error = %e, "Failed to create session");
66                            }
67                        }
68                    });
69                }
70                Err(e) => {
71                    tracing::error!(error = %e, "Failed to accept connection");
72                }
73            }
74        }
75    }
76}