chiark / gitweb /
identify links
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 24 Jul 2021 17:17:58 +0000 (18:17 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 24 Jul 2021 17:18:04 +0000 (18:18 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/config.rs
src/prelude.rs
src/types.rs

index 59556a96a0a7fb31f5fd49ad31fcd6219cb2d15d..a6dc722da7c51881b18f6c926d9927e3b8d1aeca 100644 (file)
@@ -330,133 +330,66 @@ impl Aggregate {
   }
 }
 
-#[derive(Debug)]
-enum Which<T> {
-  All,
-  These(T),
-}
+impl Aggregate {
+  fn instances(&self, only_server: Option<&ServerName>) -> BTreeSet<LinkName> {
+    let mut links:              BTreeSet<LinkName> = 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<MeansForEnd<'s>> {
-    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<N>(&self, us: N) -> Vec<LinkName>
-  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")?;
 
index 370f948f74d186e46c6b4c2b597232966bc513ad..b46e2d95a904aa10d8b8d2db80ab5a6707900d89 100644 (file)
@@ -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;
index ad590c083d7ecc7a6d1adc91c2cb6f96e70d09b4..25c9826ca3d77c4ea76d1bf4e80b5dcf6a34c98a 100644 (file)
@@ -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,