nullnet_libwallguard/
lib.rs

1use std::time::Duration;
2pub use tonic::Streaming;
3use tonic::transport::Channel;
4use tonic::{Request, Status};
5
6pub use proto::wallguard_commands::wall_guard_command::*;
7pub use proto::wallguard_commands::*;
8
9use proto::wallguard_service::wall_guard_client::*;
10pub use proto::wallguard_service::*;
11
12mod proto;
13
14#[derive(Clone, Debug)]
15pub struct WallGuardGrpcInterface {
16    client: WallGuardClient<Channel>,
17}
18
19impl WallGuardGrpcInterface {
20    #[allow(clippy::missing_panics_doc)]
21    pub async fn new(addr: &str, port: u16) -> Self {
22        let s = format!("http://{addr}:{port}");
23
24        let Ok(channel) = Channel::from_shared(s)
25            .expect("Failed to parse address")
26            .timeout(Duration::from_secs(10))
27            .connect()
28            .await
29        else {
30            // @TODO: Perhaps jusr return an error and let client deal with it ?
31            log::warn!("Failed to connect to the server. Retrying in 10 seconds...");
32            tokio::time::sleep(std::time::Duration::from_secs(10)).await;
33            return Box::pin(WallGuardGrpcInterface::new(addr, port)).await;
34        };
35
36        Self {
37            client: WallGuardClient::new(channel).max_decoding_message_size(50 * 1024 * 1024),
38        }
39    }
40
41    pub async fn request_control_channel(
42        &self,
43        app_id: &str,
44        app_secret: &str,
45    ) -> Result<Streaming<WallGuardCommand>, Status> {
46        let request = Request::new(ControlChannelRequest {
47            app_id: app_id.into(),
48            app_secret: app_secret.into(),
49        });
50
51        self.client
52            .clone()
53            .control_channel(request)
54            .await
55            .map(tonic::Response::into_inner)
56    }
57}