summaryrefslogtreecommitdiff
path: root/src/daemon_dbus.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon_dbus.rs')
-rw-r--r--src/daemon_dbus.rs90
1 files changed, 68 insertions, 22 deletions
diff --git a/src/daemon_dbus.rs b/src/daemon_dbus.rs
index 7065eec..5ed4d94 100644
--- a/src/daemon_dbus.rs
+++ b/src/daemon_dbus.rs
@@ -1,30 +1,69 @@
use base64::prelude::*;
-use dbus::{channel::MatchingReceiver, message::MatchRule};
-use dbus_crossroads::{Context, Crossroads, MethodErr};
-use defguard_wireguard_rs::{
- host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
+use dbus::{
+ channel::{MatchingReceiver, Token},
+ message::MatchRule,
+ nonblock::SyncConnection,
};
+use dbus_crossroads::{Context, Crossroads, MethodErr};
+use defguard_wireguard_rs::{key::Key, net::IpAddrMask, WireguardInterfaceApi};
use log::{debug, error, info, warn};
use rand::Rng;
use std::{
- collections::{BTreeSet, HashMap},
- marker::PhantomData,
- ops::DerefMut,
- str::FromStr,
+ collections::HashMap, marker::PhantomData, ops::DerefMut, path::PathBuf, str::FromStr,
sync::Arc,
};
-use tokio::{
- net::TcpListener,
- sync::{broadcast, RwLock},
- task,
-};
+use tokio::{net::TcpListener, sync::RwLock, task};
+
+use crate::{daemon::*, daemon_config::*, daemon_network::*};
+
+pub async fn start_dbus(
+ state: Arc<RwLock<State>>,
+ config_path: PathBuf,
+) -> Result<(Arc<SyncConnection>, Token), DaemonError> {
+ let mut cr = Crossroads::new();
+ let if_token = cr.register("de.a.maesch", move |b| {
+ b.signal::<(String, String), _>("Proposal", ("network", "peer_data"));
+ b.method_with_cr_async(
+ "AddNetwork",
+ ("name", "key", "ip", "listen_port", "maesch_port"),
+ ("success",),
+ move |ctx, _, args: (String, String, String, u16, u16)| {
+ debug!("Received AddNetwork");
+ handle_add_network(ctx, state.clone(), config_path.clone(), args)
+ },
+ );
+ });
+ cr.insert("/de/a/maesch", &[if_token], ());
+
+ // drive dbus interface
+ let (res, c) = dbus_tokio::connection::new_system_sync()?;
+ cr.set_async_support(Some((
+ c.clone(),
+ Box::new(|x| {
+ tokio::spawn(x);
+ }),
+ )));
+ let _ = tokio::spawn(print_error(async {
+ res.await;
+ Result::<!, &'static str>::Err("lost connection to dbus!")
+ }));
+ let receive_token = c.start_receive(
+ MatchRule::new_method_call(),
+ Box::new(move |msg, conn| {
+ cr.handle_message(msg, conn).unwrap();
+ true
+ }),
+ );
+ c.request_name("de.a.maesch", false, true, false).await?;
-use crate::{daemon::*, daemon_network::*};
+ Ok((c, receive_token))
+}
// TODO also take peers
pub async fn handle_add_network(
mut ctx: Context,
state: Arc<RwLock<State>>,
+ config_path: PathBuf,
(name, may_key, may_ip, may_lp, may_mp): (String, String, String, u16, u16),
) -> PhantomData<(bool,)> {
// NOTE: this is kinda stupid: we convert to a string later anyways, as thats what
@@ -55,11 +94,7 @@ pub async fn handle_add_network(
let lp = if may_lp == 0 { 25565 } else { may_lp };
let mp = if may_mp == 0 { 51820 } else { may_mp };
- let mut state_rw_guard = state.write().await;
- let state_rw = state_rw_guard.deref_mut();
-
- let wg_api = match add_network(
- &mut state_rw.hostfile,
+ let (wg_api, hostnames) = match add_network(
name.clone(),
key.to_string(),
ip_string,
@@ -68,14 +103,13 @@ pub async fn handle_add_network(
)
.await
{
- Ok(wg_api) => wg_api,
+ Ok(v) => v,
Err(e) => {
warn!("AddNetwork couldn't add network: {e}");
return ctx.reply(Err(MethodErr::failed(&e)));
}
};
- // TODO ins wg_api
let listener = match TcpListener::bind((ip, mp)).await {
Ok(l) => l,
Err(e) => {
@@ -90,9 +124,21 @@ pub async fn handle_add_network(
name.clone(),
)));
+ let mut state_rw_guard = state.write().await;
+ let state_rw = state_rw_guard.deref_mut();
state_rw.nw_handles.insert(name.clone(), (wg_api, h));
- // TODO save new config
+ // NOTE this _is_ thread-safe, as we hold an exclusive write handle to the state.
+ match write_config(&state_rw.conf, &config_path) {
+ Ok(_) => info!("Synced config"),
+ Err(e) => error!("Couldn't sync config: {e}"),
+ }
+ // similarly, this is still racy w.r.t. other processes running on the system, but at least
+ // no other thread from this program should be able to concurrently call this
+ match sync_hostnames(&hostnames) {
+ Ok(_) => (),
+ Err(e) => error!("Failed to sync hostnames to disk: {e}"),
+ };
ctx.reply(Ok((true,)))
}