-
-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathclient.rs
More file actions
70 lines (66 loc) · 2.79 KB
/
client.rs
File metadata and controls
70 lines (66 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::sync::LazyLock;
use hyper_util::rt::TokioIo;
#[cfg(windows)]
use tokio::net::windows::named_pipe::ClientOptions;
#[cfg(unix)]
use tokio::net::UnixStream;
use tonic::transport::channel::{Channel, Endpoint};
#[cfg(unix)]
use tonic::transport::Uri;
use tower::service_fn;
#[cfg(windows)]
use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;
use crate::service::proto::defguard::client::v1::desktop_daemon_service_client::DesktopDaemonServiceClient;
#[cfg(unix)]
use super::daemon::DAEMON_SOCKET_PATH;
#[cfg(windows)]
use super::named_pipe::PIPE_NAME;
pub(crate) static DAEMON_CLIENT: LazyLock<DesktopDaemonServiceClient<Channel>> =
LazyLock::new(|| {
debug!("Setting up gRPC client");
// URL is ignored since we provide our own connectors for unix socket and windows named pipes.
let endpoint = Endpoint::from_static("http://localhost");
let channel;
#[cfg(unix)]
{
channel = endpoint.connect_with_connector_lazy(service_fn(|_: Uri| async {
// Connect to a Unix domain socket.
let stream = match UnixStream::connect(DAEMON_SOCKET_PATH).await {
Ok(stream) => stream,
Err(err) if err.kind() == std::io::ErrorKind::PermissionDenied => {
error!(
"Permission denied for UNIX domain socket; please refer to \
https://docs.defguard.net/support-1/troubleshooting#\
unix-socket-permission-errors-when-desktop-client-attempts-to-connect-\
to-vpn-on-linux-machines"
);
return Err(err);
}
Err(err) => {
error!("Problem connecting to UNIX domain socket: {err}");
return Err(err);
}
};
info!("Created unix gRPC client");
Ok::<_, std::io::Error>(TokioIo::new(stream))
}));
};
#[cfg(windows)]
{
channel = endpoint.connect_with_connector_lazy(service_fn(|_| async {
let client = loop {
match ClientOptions::new().open(PIPE_NAME) {
Ok(client) => break client,
Err(err) if err.raw_os_error() == Some(ERROR_PIPE_BUSY as i32) => (),
Err(err) => {
error!("Problem connecting to named pipe: {err}");
return Err(err);
}
}
};
info!("Created windows gRPC client");
Ok::<_, std::io::Error>(TokioIo::new(client))
}));
}
DesktopDaemonServiceClient::new(channel)
});