nullnet_libwallguard/
lib.rs

1use std::time::Duration;
2use tonic::transport::Channel;
3use tonic::{Request, Streaming};
4
5use crate::proto::wallguard::wall_guard_client::WallGuardClient;
6pub use crate::proto::wallguard::*;
7
8mod proto;
9
10#[derive(Clone)]
11pub struct WallGuardGrpcInterface {
12    client: WallGuardClient<Channel>,
13}
14
15// static CA_CERT: once_cell::sync::Lazy<Certificate> = once_cell::sync::Lazy::new(|| {
16//     Certificate::from_pem(
17//         std::fs::read_to_string("tls/ca.pem").expect("Failed to read CA certificate"),
18//     )
19// });
20
21impl WallGuardGrpcInterface {
22    #[allow(clippy::missing_panics_doc)]
23    pub async fn new(addr: &str, port: u16) -> Self {
24        // let tls = ClientTlsConfig::new().ca_certificate(CA_CERT.to_owned());
25        let s = format!("http://{addr}:{port}");
26
27        let Ok(channel) = Channel::from_shared(s)
28            .expect("Failed to parse address")
29            .timeout(Duration::from_secs(10))
30            // .tls_config(tls)
31            // .expect("Failed to configure up TLS")
32            .connect()
33            .await
34        else {
35            log::warn!("Failed to connect to the server. Retrying in 10 seconds...");
36            tokio::time::sleep(std::time::Duration::from_secs(10)).await;
37            return Box::pin(WallGuardGrpcInterface::new(addr, port)).await;
38        };
39
40        Self {
41            client: WallGuardClient::new(channel).max_decoding_message_size(50 * 1024 * 1024),
42        }
43    }
44
45    #[allow(clippy::missing_errors_doc)]
46    pub async fn heartbeat(
47        &mut self,
48        app_id: String,
49        app_secret: String,
50        device_version: String,
51        device_uuid: String,
52    ) -> Result<Streaming<HeartbeatResponse>, String> {
53        self.client
54            .heartbeat(Request::new(HeartbeatRequest {
55                app_id,
56                app_secret,
57                device_version,
58                device_uuid,
59            }))
60            .await
61            .map(tonic::Response::into_inner)
62            .map_err(|e| e.to_string())
63    }
64
65    #[allow(clippy::missing_errors_doc)]
66    pub async fn handle_packets(&mut self, message: Packets) -> Result<CommonResponse, String> {
67        self.client
68            .handle_packets(Request::new(message))
69            .await
70            .map(tonic::Response::into_inner)
71            .map_err(|e| e.to_string())
72    }
73
74    #[allow(clippy::missing_errors_doc)]
75    pub async fn handle_config(
76        &mut self,
77        message: ConfigSnapshot,
78    ) -> Result<CommonResponse, String> {
79        self.client
80            .handle_config(Request::new(message))
81            .await
82            .map(tonic::Response::into_inner)
83            .map_err(|e| e.to_string())
84    }
85
86    #[allow(clippy::missing_errors_doc)]
87    pub async fn handle_logs(&mut self, message: Logs) -> Result<CommonResponse, String> {
88        self.client
89            .handle_logs(Request::new(message))
90            .await
91            .map(tonic::Response::into_inner)
92            .map_err(|e| e.to_string())
93    }
94
95    #[allow(clippy::missing_errors_doc)]
96    pub async fn request_control_channel(
97        &mut self,
98        token: String,
99        session_type: String,
100    ) -> Result<ControlChannelResponse, String> {
101        let response = self
102            .client
103            .request_control_channel(Request::new(ControlChannelRequest {
104                token,
105                session_type,
106            }))
107            .await
108            .map(tonic::Response::into_inner)
109            .map_err(|e| e.to_string())?;
110
111        Ok(response)
112    }
113}