nullnet_libwallguard/
lib.rs

1use std::time::Duration;
2use tonic::transport::Channel;
3use tonic::Request;
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 login(&mut self, app_id: String, app_secret: String) -> Result<String, String> {
47        let response = self
48            .client
49            .login(Request::new(LoginRequest { app_id, app_secret }))
50            .await
51            .map_err(|e| e.to_string())?;
52
53        Ok(response.into_inner().token)
54    }
55
56    #[allow(clippy::missing_errors_doc)]
57    pub async fn heartbeat(&mut self, token: String) -> Result<HeartbeatResponse, String> {
58        self.client
59            .heartbeat(Request::new(HeartbeatRequest {
60                auth: Some(Authentication { token }),
61            }))
62            .await
63            .map(tonic::Response::into_inner)
64            .map_err(|e| e.to_string())
65    }
66
67    #[allow(clippy::missing_errors_doc)]
68    pub async fn handle_packets(&mut self, message: Packets) -> Result<CommonResponse, String> {
69        self.client
70            .handle_packets(Request::new(message))
71            .await
72            .map(tonic::Response::into_inner)
73            .map_err(|e| e.to_string())
74    }
75
76    #[allow(clippy::missing_errors_doc)]
77    pub async fn handle_config(
78        &mut self,
79        message: ConfigSnapshot,
80    ) -> Result<CommonResponse, String> {
81        self.client
82            .handle_config(Request::new(message))
83            .await
84            .map(tonic::Response::into_inner)
85            .map_err(|e| e.to_string())
86    }
87
88    #[allow(clippy::missing_errors_doc)]
89    pub async fn handle_logs(&mut self, message: Logs) -> Result<CommonResponse, String> {
90        self.client
91            .handle_logs(Request::new(message))
92            .await
93            .map(tonic::Response::into_inner)
94            .map_err(|e| e.to_string())
95    }
96
97    #[allow(clippy::missing_errors_doc)]
98    pub async fn setup_client(&mut self, request: SetupRequest) -> Result<CommonResponse, String> {
99        self.client
100            .setup(Request::new(request))
101            .await
102            .map(tonic::Response::into_inner)
103            .map_err(|e| e.to_string())
104    }
105
106    #[allow(clippy::missing_errors_doc)]
107    pub async fn device_status(&mut self, token: String) -> Result<StatusResponse, String> {
108        let response = self
109            .client
110            .status(Request::new(StatusRequest {
111                auth: Some(Authentication { token }),
112            }))
113            .await
114            .map(tonic::Response::into_inner)
115            .map_err(|e| e.to_string())?;
116
117        Ok(response)
118    }
119}