use anyhow::Result; use tokio::try_join; use crate::{ config::ConfigOpts, consul_actor::ConsulActor, fw_actor::FirewallActor, igd_actor::IgdActor, stun_actor::StunActor, }; pub struct Diplonat { consul: ConsulActor, firewall: FirewallActor, igd: Option, stun: StunActor, } impl Diplonat { pub async fn new() -> Result { let rt_cfg = ConfigOpts::from_env()?; println!("{:#?}", rt_cfg); let ca = ConsulActor::new(&rt_cfg.consul, &rt_cfg.consul.node_name); let fw = FirewallActor::new( rt_cfg.firewall.ipv6_only, rt_cfg.firewall.refresh_time, &ca.rx_open_ports, ) .await?; let ia = match rt_cfg.igd { Some(igdc) => Some( IgdActor::new( igdc.private_ip, igdc.refresh_time, igdc.expiration_time, &ca.rx_open_ports, ) .await?, ), None => None, }; let sa = StunActor::new(&rt_cfg.consul, &rt_cfg.stun, &rt_cfg.consul.node_name); let ctx = Self { consul: ca, igd: ia, firewall: fw, stun: sa, }; Ok(ctx) } pub async fn listen(&mut self) -> Result<()> { let igd_opt = &mut self.igd; try_join!( self.consul.listen(), async { if let Some(igd) = igd_opt { igd.listen().await } else { Ok(()) } }, self.firewall.listen(), self.stun.listen(), )?; Ok(()) } }