From abb5cdbe065a3c078055b6c1920b4b13aa5ded51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 30 Mar 2023 16:43:58 +0100 Subject: [PATCH] extracted domain and ipnet information to separate struct --- .../src/allowed_hosts/group.rs | 55 +++++++++++++++++++ .../src/allowed_hosts/host.rs | 21 ------- .../src/allowed_hosts/hosts.rs | 34 ++++-------- .../src/allowed_hosts/mod.rs | 1 + .../src/allowed_hosts/standard_list.rs | 3 + 5 files changed, 69 insertions(+), 45 deletions(-) create mode 100644 service-providers/network-requester/src/allowed_hosts/group.rs diff --git a/service-providers/network-requester/src/allowed_hosts/group.rs b/service-providers/network-requester/src/allowed_hosts/group.rs new file mode 100644 index 0000000000..a5cdeba7d6 --- /dev/null +++ b/service-providers/network-requester/src/allowed_hosts/group.rs @@ -0,0 +1,55 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::allowed_hosts::host::Host; +use ipnetwork::IpNetwork; +use std::collections::HashSet; +use std::net::IpAddr; + +/// A simpled grouped set of hosts. +/// It ignores any port information. +#[derive(Debug)] +pub(crate) struct HostsGroup { + pub(super) domains: HashSet, + pub(super) ip_nets: Vec, +} + +impl HostsGroup { + pub(crate) fn new(raw_hosts: Vec) -> HostsGroup { + let mut domains = HashSet::new(); + let mut ip_nets = Vec::new(); + + for host in raw_hosts { + match host { + Host::Domain(domain) => { + domains.insert(domain); + } + Host::IpNetwork(ipnet) => ip_nets.push(ipnet), + } + } + + HostsGroup { domains, ip_nets } + } + + pub(crate) fn contains_domain(&self, host: &str) -> bool { + self.domains.contains(&host.to_string()) + } + + pub(super) fn contains_ip_address(&self, address: IpAddr) -> bool { + for ip_net in &self.ip_nets { + if ip_net.contains(address) { + return true; + } + } + + false + } + + pub(super) fn add_ip(&mut self, ip: IpAddr) { + self.ip_nets.push(ip.into()); + } + + pub(super) fn add_domain(&mut self, domain: &str) { + self.domains.insert(domain.to_string()); + } +} diff --git a/service-providers/network-requester/src/allowed_hosts/host.rs b/service-providers/network-requester/src/allowed_hosts/host.rs index e9a61b22d1..8eae18b934 100644 --- a/service-providers/network-requester/src/allowed_hosts/host.rs +++ b/service-providers/network-requester/src/allowed_hosts/host.rs @@ -7,27 +7,6 @@ pub(crate) enum Host { IpNetwork(IpNetwork), } -impl Host { - /// Returns true if the host is a domain, false if it is an ip network - pub(crate) fn is_domain(&self) -> bool { - matches!(self, Host::Domain(..)) - } - - pub(crate) fn extract_domain(self) -> String { - match self { - Host::Domain(domain) => domain, - _ => panic!("called extract domain on an ipnet!"), - } - } - - pub(crate) fn extract_ipnetwork(self) -> IpNetwork { - match self { - Host::IpNetwork(ipnet) => ipnet, - _ => panic!("called extract ipnet on a domain!"), - } - } -} - // TODO: perhaps in the future it should do some domain validation? // // So for example if somebody put some nonsense in the whitelist file like "foomp", diff --git a/service-providers/network-requester/src/allowed_hosts/hosts.rs b/service-providers/network-requester/src/allowed_hosts/hosts.rs index ee1dba95cf..99d82585ea 100644 --- a/service-providers/network-requester/src/allowed_hosts/hosts.rs +++ b/service-providers/network-requester/src/allowed_hosts/hosts.rs @@ -1,22 +1,18 @@ +use super::host::Host; +use crate::allowed_hosts::group::HostsGroup; use std::{ - collections::HashSet, fs::{self, File, OpenOptions}, io::{self, BufRead, BufReader}, net::IpAddr, path::{Path, PathBuf}, }; -use super::host::Host; -use ipnetwork::IpNetwork; - /// A simple file-backed store for information about allowed / unknown hosts. /// It ignores any port information. #[derive(Debug)] pub(crate) struct HostsStore { pub(super) storefile: PathBuf, - - pub(super) domains: HashSet, - pub(super) ip_nets: Vec, + pub(super) data: HostsGroup, } impl HostsStore { @@ -37,40 +33,30 @@ impl HostsStore { hosts.extend(standard_hosts.unwrap_or_default()); } - let (domains, ip_nets): (Vec<_>, Vec<_>) = - hosts.into_iter().partition(|host| host.is_domain()); - HostsStore { storefile, - domains: domains.into_iter().map(Host::extract_domain).collect(), - ip_nets: ip_nets.into_iter().map(Host::extract_ipnetwork).collect(), + data: HostsGroup::new(hosts), } } pub(crate) fn contains_domain(&self, host: &str) -> bool { - self.domains.contains(&host.to_string()) + self.data.contains_domain(host) } pub(super) fn contains_ip_address(&self, address: IpAddr) -> bool { - for ip_net in &self.ip_nets { - if ip_net.contains(address) { - return true; - } - } - - false + self.data.contains_ip_address(address) } pub(super) fn add_ip(&mut self, ip: IpAddr) { if !self.contains_ip_address(ip) { - self.ip_nets.push(ip.into()); + self.data.add_ip(ip); self.append_to_file(&ip.to_string()); } } pub(super) fn add_domain(&mut self, domain: &str) { if !self.contains_domain(domain) { - self.domains.insert(domain.to_string()); + self.data.add_domain(domain); self.append_to_file(domain); } } @@ -135,7 +121,7 @@ mod constructor_tests { #[test] fn works_with_no_standard_hosts() { let store = HostsStore::new(PathBuf::from("/tmp"), PathBuf::from("foomp.db"), None); - assert_eq!(store.domains.len(), 0); + assert_eq!(store.data.domains.len(), 0); } #[test] @@ -148,7 +134,7 @@ mod constructor_tests { Host::from(String::from("foomp.com")), ]), ); - assert_eq!(store.domains.len(), 2); + assert_eq!(store.data.domains.len(), 2); assert!(store.contains_domain("google.com")); assert!(store.contains_domain("foomp.com")); } diff --git a/service-providers/network-requester/src/allowed_hosts/mod.rs b/service-providers/network-requester/src/allowed_hosts/mod.rs index 621f068c05..390abf8603 100644 --- a/service-providers/network-requester/src/allowed_hosts/mod.rs +++ b/service-providers/network-requester/src/allowed_hosts/mod.rs @@ -2,6 +2,7 @@ mod filter; mod host; mod hosts; mod standard_list; +mod group; pub(crate) use filter::OutboundRequestFilter; pub(crate) use hosts::HostsStore; diff --git a/service-providers/network-requester/src/allowed_hosts/standard_list.rs b/service-providers/network-requester/src/allowed_hosts/standard_list.rs index 3db6bc2550..52179b0e3e 100644 --- a/service-providers/network-requester/src/allowed_hosts/standard_list.rs +++ b/service-providers/network-requester/src/allowed_hosts/standard_list.rs @@ -1,3 +1,6 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + use crate::allowed_hosts::host::Host; /// Fetch the standard allowed list from nymtech.net