openvpn3_rs/helpers/
client.rs1use super::{Configuration, Session};
2
3use crate::{
4 sessions::{LogStream, SessionManagerEventStream},
5 ConfigurationProxy, NetCfgProxy, Result, SessionsProxy,
6};
7
8use futures_util::future;
9use zbus::{fdo::PeerProxy, zvariant::OwnedObjectPath, Connection};
10
11#[derive(Clone, Debug)]
15pub struct OpenVPN3<'a> {
16 connection: Connection,
17 peer_proxy: PeerProxy<'a>,
18 sessions_proxy: SessionsProxy<'a>,
19 configuration_manager_proxy: ConfigurationProxy<'a>,
20}
21impl<'a> OpenVPN3<'a> {
22 pub async fn connect() -> Result<OpenVPN3<'a>> {
24 let connection = Connection::system().await?;
25 let sessions_proxy = SessionsProxy::new(&connection).await?;
26 let peer_proxy = PeerProxy::builder(&connection)
27 .destination("net.openvpn.v3.sessions")?
28 .path(sessions_proxy.path().to_owned())?
29 .build()
30 .await?;
31 let configuration_manager_proxy = ConfigurationProxy::new(&connection).await?;
32
33 Ok(OpenVPN3 {
34 connection,
35 peer_proxy,
36 sessions_proxy,
37 configuration_manager_proxy,
38 })
39 }
40
41 pub async fn configurations(&'a self) -> Result<Vec<Configuration<'a>>> {
43 let configs = self
44 .configuration_manager_proxy
45 .fetch_available_configs()
46 .await?;
47
48 futures_util::future::join_all(configs.into_iter().map(|object_path| {
49 Configuration::new(
50 self.connection.clone(),
51 object_path,
54 )
55 }))
56 .await
57 .into_iter()
58 .collect::<Result<_>>()
59 }
60
61 pub async fn import<'c>(
63 &self,
64 name: &str,
65 config_str: &str,
66 single_use: bool,
67 persistent: bool,
68 ) -> Result<Configuration<'c>> {
69 self.ping().await?;
70
71 let proxy = self
72 .configuration_manager_proxy
73 .import(name, config_str, single_use, persistent)
74 .await?;
75
76 Ok(Configuration::new(
77 self.connection.clone(),
78 OwnedObjectPath::from(proxy.path().clone()),
79 )
80 .await?)
81
82 }
90
91 pub async fn sessions(&'a self) -> Result<Vec<Session<'a>>> {
93 self.ping().await?;
94
95 let sessions = self.sessions_proxy.fetch_available_sessions().await?;
96
97 futures_util::future::join_all(sessions.into_iter().map(|object_path| {
98 Session::new(
99 self.connection.clone(),
100 object_path,
101 )
102 }))
103 .await
104 .into_iter()
105 .collect::<Result<_>>()
106 }
107
108 pub async fn interfaces(&'a self) -> Result<Vec<String>> {
109 self.ping().await?;
110
111 let interfaces = self.sessions_proxy.fetch_managed_interfaces().await?;
112 Ok(interfaces)
113 }
114
115 pub async fn net_cfg_manager(&'a self) -> Result<NetCfgProxy<'static>> {
116 Ok(NetCfgProxy::new(&self.connection).await?)
117 }
118
119 pub async fn event_stream(&self) -> Result<SessionManagerEventStream<'a>> {
120 Ok(self.sessions_proxy.receive_session_manager_event().await?)
121 }
122
123 pub async fn log_stream(&self) -> Result<LogStream<'a>> {
124 Ok(self.sessions_proxy.receive_log().await?)
125 }
126
127 async fn ping(&'a self) -> Result<()> {
128 let mut attempts = 10;
129
130 while attempts > 0 {
131 let results = future::join(self.peer_proxy.ping(), self.sessions_proxy.version()).await;
132
133 if results.0.is_ok() && results.1.is_ok() {
134 return Ok(());
135 }
136
137 attempts -= 1;
138 }
139
140 Ok(())
141 }
142}