dsf-daemon 0.1.3

Distributed Service Framework (DSF) Daemon
//! Local address discovery plugin
//! Allows the daemon to perform local address discovery

use std::net::IpAddr;

extern crate get_if_addrs;
use get_if_addrs::get_if_addrs;

/// Commands handled by the address helper plugin
#[derive(Clone, Debug, PartialEq)]
pub enum AddressCommand {
    Discover,
}

/// Responses / updates generated by the address plugin
#[derive(Clone, Debug, PartialEq)]
pub enum AddressUpdate {
    None,
    Discovered(Vec<IpAddr>),
    Removed(IpAddr),
}

/// AddressActor provides local address lookup / update services
pub struct AddressPlugin {
    known: Vec<IpAddr>,
}

impl AddressPlugin {
    pub fn new() -> Self {
        Self { known: vec![] }
    }

    /// Update known addresses
    pub async fn update(&mut self) -> Result<(), std::io::Error> {
        // Fetch locateable addresses
        let res = self.get_addrs().await?;

        // Find new addresses
        let mut added = vec![];
        for i in &res {
            if !self.known.contains(i) {
                added.push(i.clone());
                self.known.push(i.clone());
            }
        }

        // Find removed addresses
        let mut removed = vec![];
        for i in 0..self.known.len() {
            let a = &self.known[i];

            if !res.contains(a) {
                removed.push(a.clone());
                self.known.remove(i);
            }
        }

        info!("Discovered: {:?} Removed: {:?}", added, removed);

        Ok(())
    }

    /// Fetch known addresses
    pub async fn get_addrs(&mut self) -> Result<Vec<IpAddr>, std::io::Error> {
        let a = get_if_addrs()?;

        let a = a
            .iter()
            .map(|v| v.ip().clone())
            .filter(|v| !v.is_loopback())
            .collect();

        Ok(a)
    }
}