blob: 70133f1cbd02bf647358e83765fba5352859f94f [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Manages services
// In case we roll the toolchain and something we're using as a feature has been
// stabilized.
#![allow(stable_features)]
// TODO(dpradilla): reenable and add comments #![deny(missing_docs)]
#![deny(unreachable_patterns)]
#![deny(unused)]
// TODO(dpradilla): remove allow
#![allow(dead_code)]
use crate::lifmgr::LIF;
use crate::{error, UUID};
use std::collections::HashSet;
/// `Manager` keeps track of interfaces where a service is enabled
/// and verifies conflicting services are not enabled.
pub struct Manager {
// dhcp_server has collection of interfaces where DHCP dhcp_server is enabled.
dhcp_server: std::collections::HashSet<UUID>,
// dhcp_client has collection of interfaces DHCP dhcp_client is enabled.
dhcp_client: std::collections::HashSet<UUID>,
}
impl Manager {
//! Creates a new Manager.
pub fn new() -> Self {
Manager { dhcp_server: HashSet::new(), dhcp_client: HashSet::new() }
}
/// `enable_server` sets dhcp dhcp_server as enabled on indicated interface.
pub fn enable_server(&mut self, lif: &LIF) -> error::Result<bool> {
if self.dhcp_client.contains(&lif.id().uuid) {
return Err(error::NetworkManager::SERVICE(error::Service::NotEnabled));
}
Ok(self.dhcp_server.insert(lif.id().uuid))
}
/// `disable_server` sets dhcp dhcp_server as disable on indicated interface.
pub fn disable_server(&mut self, lif: &LIF) -> bool {
self.dhcp_server.remove(&lif.id().uuid)
}
/// `is_server_enabled` returns true if the DHCP dhcp_server is enabled on indicated interface.
pub fn is_server_enabled(&mut self, lif: &LIF) -> bool {
self.dhcp_server.contains(&lif.id().uuid)
}
/// `enable_client` sets dhcp dhcp_client as enabled on indicated interface.
pub fn enable_client(&mut self, lif: &LIF) -> error::Result<bool> {
if self.dhcp_server.contains(&lif.id().uuid) {
return Err(error::NetworkManager::SERVICE(error::Service::NotEnabled));
}
Ok(self.dhcp_client.insert(lif.id().uuid))
}
/// `disable_client` sets dhcp dhcp_client as disable on indicated interface.
pub fn disable_client(&mut self, lif: &LIF) -> bool {
self.dhcp_client.remove(&lif.id().uuid)
}
/// `is_client_enabled` returns true if the DHCP dhcp_client is enabled on indicated interface.
pub fn is_client_enabled(&mut self, lif: &LIF) -> bool {
self.dhcp_client.contains(&lif.id().uuid)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::lifmgr::{LIFType, LIF};
use crate::portmgr::PortId;
use crate::portmgr::{Port, PortManager};
fn create_lifs() -> (LIF, LIF) {
let mut pm = PortManager::new();
pm.add_port(Port::new(PortId::from(1), "port1", 1));
pm.add_port(Port::new(PortId::from(2), "port2", 1));
let l1 =
LIF::new(1, LIFType::WAN, "name1", PortId::from(0), vec![PortId::from(1)], 0, None)
.unwrap();
let l2 =
LIF::new(2, LIFType::LAN, "name2", PortId::from(0), vec![PortId::from(2)], 0, None)
.unwrap();
(l1, l2)
}
#[test]
fn test_service_manager_new() {
let m = Manager::new();
assert_eq!(m.dhcp_server.len(), 0);
assert_eq!(m.dhcp_client.len(), 0);
}
#[test]
fn test_server_enable() {
let mut m = Manager::new();
let (l, _) = create_lifs();
assert!(m.enable_server(&l).unwrap_or(false));
assert_eq!(m.dhcp_server.len(), 1);
}
#[test]
fn test_server_double_enable() {
let mut m = Manager::new();
let (l, _) = create_lifs();
assert!(m.enable_server(&l).unwrap_or(false));
assert!(!m.enable_server(&l).unwrap_or(false));
assert_eq!(m.dhcp_server.len(), 1);
}
#[test]
fn test_disable_server() {
let mut m = Manager::new();
let (l, l2) = create_lifs();
assert!(m.enable_server(&l).unwrap_or(false));
assert_eq!(m.dhcp_server.len(), 1);
assert!(m.disable_server(&l));
assert_eq!(m.dhcp_server.len(), 0);
assert!(m.enable_server(&l).unwrap_or(false));
assert!(m.enable_server(&l2).unwrap_or(false));
assert_eq!(m.dhcp_server.len(), 2);
assert!(m.disable_server(&l));
assert_eq!(m.dhcp_server.len(), 1);
}
#[test]
fn test_server_disable_already_disabled() {
let mut m = Manager::new();
let (l, _) = create_lifs();
assert!(!m.disable_server(&l));
assert_eq!(m.dhcp_server.len(), 0);
}
#[test]
fn test_client_enable() {
let mut m = Manager::new();
let (l, _) = create_lifs();
assert!(m.enable_client(&l).unwrap_or(false));
assert_eq!(m.dhcp_client.len(), 1);
}
#[test]
fn test_client_double_enable() {
let mut m = Manager::new();
let (l, _) = create_lifs();
assert!(m.enable_client(&l).unwrap_or(false));
assert!(!m.enable_client(&l).unwrap_or(false));
assert_eq!(m.dhcp_client.len(), 1);
}
#[test]
fn test_disable_client() {
let mut m = Manager::new();
let (l, l2) = create_lifs();
assert!(m.enable_client(&l).unwrap_or(false));
assert_eq!(m.dhcp_client.len(), 1);
assert!(m.disable_client(&l));
assert_eq!(m.dhcp_client.len(), 0);
assert!(m.enable_client(&l).unwrap_or(false));
assert!(m.enable_client(&l2).unwrap_or(false));
assert_eq!(m.dhcp_client.len(), 2);
assert!(m.disable_client(&l));
assert_eq!(m.dhcp_client.len(), 1);
}
#[test]
fn test_client_disable_already_disabled() {
let mut m = Manager::new();
let (l, _) = create_lifs();
assert!(!m.disable_client(&l));
assert_eq!(m.dhcp_client.len(), 0);
}
#[test]
fn test_enable_server_with_client_enabled() {
let mut m = Manager::new();
let (l, _) = create_lifs();
assert!(m.enable_client(&l).unwrap_or(false));
assert_eq!(m.dhcp_client.len(), 1);
assert!(!m.enable_server(&l).unwrap_or(false));
assert_eq!(m.dhcp_server.len(), 0);
}
#[test]
fn test_enable_client_with_server_enabled() {
let mut m = Manager::new();
let (l, _) = create_lifs();
assert!(m.enable_server(&l).unwrap_or(false));
assert_eq!(m.dhcp_server.len(), 1);
assert!(!m.enable_client(&l).unwrap_or(false));
assert_eq!(m.dhcp_client.len(), 0);
}
}