From: Ian Jackson Date: Sat, 24 Jul 2021 17:17:58 +0000 (+0100) Subject: identify links X-Git-Tag: hippotat/1.0.0~469 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=9e34b4ec3e72beddb3df48626043a0c36481a50d;p=hippotat.git identify links Signed-off-by: Ian Jackson --- diff --git a/src/config.rs b/src/config.rs index 59556a9..a6dc722 100644 --- a/src/config.rs +++ b/src/config.rs @@ -330,133 +330,66 @@ impl Aggregate { } } -#[derive(Debug)] -enum Which { - All, - These(T), -} +impl Aggregate { + fn instances(&self, only_server: Option<&ServerName>) -> BTreeSet { + let mut links: BTreeSet = default(); -struct MeansForEnd<'m,U,P> { - us_spec: Which<&'m U>, - peer: Which<&'m P>, -} + let mut secrets_anyserver: BTreeSet<&ClientName> = default(); + let mut secrets_anyclient: BTreeSet<&ServerName> = default(); + let mut secret_global = false; -trait InstancesForEnd: Eq { - type Peer: Ord + Eq + Hash + Debug; - fn section_means<'s>(&self, s: &'s SectionName) - -> MeansForEnd<'s, Self, Peer> -} + let mut putative_servers = BTreeSet::new(); + let mut putative_clients = BTreeSet::new(); -impl InstanceForEnd for ServerName { - type Peer = ClientName; - fn section_means<'s>(&'_ self, s: &'s SectionName) - -> Option> { - use Which:*; - let (us_spec, peer) = match s { - SN::Link(l) => (These(l.server), These(l.client)), - SN::Server(server) => (These( server), All), - SN::Client(client) => (All, These( client)), - SN::Common => (All, All), - _ => return None, + let mut note_server = |s| { + if let Some(only) = only_server { if s != only { return false } } + putative_servers.insert(s); + true }; - MeansForEnd { us_spec, peer } - } -} - -impl Aggregate { - fn instances_for(&self, us: N) -> Vec - where N: InstancesForEnd, - { - use Which::*; - let mut secrets = Which::These(BTreeSet::new()); - let mut putative_selves = BTreeSet::new(); - let mut putative_peers = BTreeSet::new(); - - let matching_means = |section: &SectionName| { - let means = us.section_means(section)?; - if match means.us_spec { - These(u) => if u == us, - All => true, - } { Some(means) } else { None } + let mut note_client = |c| { + putative_clients.insert(c); }; - for (section, vars) in &self.agg.sections { - - if let Some(means) = matching_means(section) { - + for (section, vars) in &self.sections { + let has_secret = || vars.contains_key("secret"); - if ! vars.has_key("secret") { continue } - - let tsecrets = match secrets { - These(ref mut s) => s, - All => break, - }; - - if let Some(means) = matching_means(section) { - match means.peer { - Which::These(ypeer) => tsecrets.insert(ypeer), - Which::All => secrets = Which::All, - } + match section { + SN::Link(l) => { + if ! note_server(&l.server) { continue } + note_client(&l.client); + if has_secret() { links.insert(l.clone()); } + }, + SN::Server(ref s) => { + if ! note_server(s) { continue } + if has_secret() { secrets_anyclient.insert(s); } + }, + SN::Client(ref c) => { + note_client(c); + if has_secret() { secrets_anyserver.insert(c); } + }, + SN::Common => { + if has_secret() { secret_global = true; } + }, + _ => { }, } - } - let links = vec![]; - - for (section, vars) in &self.agg.sections { - - if let Some(means) = matching_means(section) { - - if match secrets { - All => true, - These(s) => s.contains(means.peer), - } { - - links.push( us. - - - match section { - SN::Link(LinkName { ref client, ref srver }) - if server == &server_name - => tclients.insert(client), - - SN::Client(ref client) - => tclients.insert(client), - - SN::Server(ref server) | SN::Common - => tclients. - - } - - - let has_secret = .iter().filter_map(|section, vars| { - - - - match section { - - SN:: - - - - let links = self.agg.sections.iter().filter_map(|section| match section { - - SN::Link(LinkName { ref client, .. }) | - SN::Client(ref client) => Some(client.clone()), - - SN::Server(_) | SN::ServerLimit(_) | - SN::GlobalLimit : SN::Common => None => None, - - }).filter(|client| { - - self.lookup_raw("secret", SKL::Ordinary).is_some() - - }).map(|client| { + // Add links which are justified by blanket secrets + for (client, server) in iproduct!( + putative_clients.into_iter().filter( + |c| secret_global || secrets_anyserver.contains(c) + ), + putative_servers.iter().cloned().filter( + |s| secret_global || secrets_anyclient.contains(s) + ) + ) { + links.insert(LinkName { + client: client.clone(), + server: server.clone(), + }); + } - - - - | + links } } @@ -684,6 +617,9 @@ pub fn read() { let server_name = agg.establish_server_name()?; + let instances = agg.instances(None); + eprintln!("{:#?}", &instances); + let link = LinkName { server: "fooxxx".parse().unwrap(), client: "127.0.0.1".parse().unwrap(), @@ -704,9 +640,6 @@ pub fn read() { ], }; - let server_name = self.establish_server_name() - .context("establish server name")?; - let ic = InstanceConfig::resolve_instance(&rctx) .context("resolve config xxx for")?; diff --git a/src/prelude.rs b/src/prelude.rs index 370f948..b46e2d9 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-or-later // There is NO WARRANTY. -pub use std::collections::HashMap; +pub use std::collections::{BTreeSet, HashMap}; pub use std::cmp::{min, max}; pub use std::fs; pub use std::fmt::{self, Debug}; @@ -18,7 +18,7 @@ pub use extend::ext; pub use fehler::{throw, throws}; pub use hyper::Uri; pub use ipnet::IpNet; -pub use itertools::Itertools; +pub use itertools::{iproduct, Itertools}; pub use lazy_regex::regex_is_match; pub use structopt::StructOpt; pub use tokio::time::Duration; diff --git a/src/types.rs b/src/types.rs index ad590c0..25c9826 100644 --- a/src/types.rs +++ b/src/types.rs @@ -6,13 +6,13 @@ use crate::prelude::*; pub enum LinkEnd { Server, Client } -#[derive(Debug,Clone,Hash,Eq,PartialEq)] +#[derive(Debug,Clone,Hash,Eq,PartialEq,Ord,PartialOrd)] pub struct ServerName(pub String); -#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)] +#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq,Ord,PartialOrd)] pub struct ClientName(pub Ipv4Addr); -#[derive(Debug,Clone,Hash,Eq,PartialEq)] +#[derive(Debug,Clone,Hash,Eq,PartialEq,Ord,PartialOrd)] pub struct LinkName { pub server: ServerName, pub client: ClientName,