Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ x25519-dalek = { version = "2", features = [
"static_secrets",
] }

[target.'cfg(unix)'.dependencies]
tokio-stream = "0.1"
tower = "0.5"
hyper-util = "0.1"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winsvc", "winerror"] }
windows-service = "0.7"
Expand Down
51 changes: 46 additions & 5 deletions src-tauri/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ pub mod utils;
#[cfg(windows)]
pub mod windows;

#[cfg(windows)]
use std::net::{Ipv4Addr, SocketAddr};
use std::{
collections::HashMap,
net::{IpAddr, Ipv4Addr, SocketAddr},
net::IpAddr,
pin::Pin,
str::FromStr,
time::{Duration, SystemTime, UNIX_EPOCH},
Expand All @@ -29,8 +31,14 @@ use proto::{
desktop_daemon_service_server::{DesktopDaemonService, DesktopDaemonServiceServer},
CreateInterfaceRequest, InterfaceData, ReadInterfaceDataRequest, RemoveInterfaceRequest,
};
#[cfg(unix)]
use std::{fs, os::unix::fs::PermissionsExt, path::Path};
use thiserror::Error;
#[cfg(unix)]
use tokio::net::UnixListener;
use tokio::{sync::mpsc, time::interval};
#[cfg(unix)]
use tokio_stream::wrappers::UnixListenerStream;
use tonic::{
codegen::tokio_stream::{wrappers::ReceiverStream, Stream},
transport::Server,
Expand All @@ -41,9 +49,13 @@ use tracing::{debug, error, info, info_span, Instrument};
use self::config::Config;
use super::VERSION;

#[cfg(windows)]
const DAEMON_HTTP_PORT: u16 = 54127;
#[cfg(windows)]
pub(super) const DAEMON_BASE_URL: &str = "http://localhost:54127";

pub(super) const DAEMON_SOCKET_PATH: &str = "/var/run/defguard.socket";

#[derive(Error, Debug)]
pub enum DaemonError {
#[error(transparent)]
Expand Down Expand Up @@ -323,16 +335,45 @@ impl DesktopDaemonService for DaemonService {
}
}

#[cfg(unix)]
pub async fn run_server(config: Config) -> anyhow::Result<()> {
debug!("Starting Defguard interface management daemon");

let daemon_service = DaemonService::new(&config);

// Remove existing socket if it exists
if Path::new(DAEMON_SOCKET_PATH).exists() {
fs::remove_file(DAEMON_SOCKET_PATH)?;
}

let uds = UnixListener::bind(DAEMON_SOCKET_PATH)?;

// Set socket permissions to allow client access
// 0o666 allows read/write for owner, group, and others
fs::set_permissions(DAEMON_SOCKET_PATH, fs::Permissions::from_mode(0o666))?;

let uds_stream = UnixListenerStream::new(uds);

info!("Defguard daemon version {VERSION} started, listening on socket {DAEMON_SOCKET_PATH}",);
debug!("Defguard daemon configuration: {config:?}");

Server::builder()
.trace_fn(|_| tracing::info_span!("defguard_service"))
.add_service(DesktopDaemonServiceServer::new(daemon_service))
.serve_with_incoming(uds_stream)
.await?;

Ok(())
}

#[cfg(windows)]
pub async fn run_server(config: Config) -> anyhow::Result<()> {
debug!("Starting Defguard interface management daemon");

let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), DAEMON_HTTP_PORT);
let daemon_service = DaemonService::new(&config);

info!(
"Defguard daemon version {} started, listening on {addr}",
VERSION
);
info!("Defguard daemon version {VERSION} started, listening on {addr}",);
debug!("Defguard daemon configuration: {config:?}");

Server::builder()
Expand Down
27 changes: 26 additions & 1 deletion src-tauri/src/service/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
use std::io::stdout;

#[cfg(windows)]
use crate::service::DAEMON_BASE_URL;
#[cfg(unix)]
use crate::service::DAEMON_SOCKET_PATH;
#[cfg(unix)]
use hyper_util::rt::TokioIo;
#[cfg(unix)]
use tokio::net::UnixStream;
use tonic::transport::channel::{Channel, Endpoint};
#[cfg(unix)]
use tonic::transport::Uri;
#[cfg(unix)]
use tower::service_fn;
use tracing::{debug, Level};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::{
Expand All @@ -9,9 +21,22 @@ use tracing_subscriber::{
};

use crate::service::{
proto::desktop_daemon_service_client::DesktopDaemonServiceClient, DaemonError, DAEMON_BASE_URL,
proto::desktop_daemon_service_client::DesktopDaemonServiceClient, DaemonError,
};

#[cfg(unix)]
pub fn setup_client() -> Result<DesktopDaemonServiceClient<Channel>, DaemonError> {
debug!("Setting up gRPC client");
let endpoint = Endpoint::try_from("http://[::]:50051")?;
let channel = endpoint.connect_with_connector_lazy(service_fn(|_: Uri| async {
// Connect to a Uds socket
Ok::<_, std::io::Error>(TokioIo::new(UnixStream::connect(DAEMON_SOCKET_PATH).await?))
}));
let client = DesktopDaemonServiceClient::new(channel);
Ok(client)
}

#[cfg(windows)]
pub fn setup_client() -> Result<DesktopDaemonServiceClient<Channel>, DaemonError> {
debug!("Setting up gRPC client");
let endpoint = Endpoint::from_shared(DAEMON_BASE_URL)?;
Expand Down