chiark / gitweb /
config: wip defaulting
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 24 Jul 2021 18:38:57 +0000 (19:38 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 24 Jul 2021 18:38:57 +0000 (19:38 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
README.config
src/config.rs

index a6db64ee578112bb670a0c2bd0d862e5d0feb9b3..4a9affad30be3bd950a030065a8288f282c3d066 100644 (file)
@@ -130,6 +130,7 @@ Ordinary settings, used by both, not client-specific:
 
   vaddr
      Address of server's virtual interface.
+     [first host entry in <vnetwork>, so 172.24.230.193]
 
   vrelay
      Virtual point-to-point address used for tunnel routing
index 560233d63027afc51da9999df23cfc5fb91ba56f..4607eb676fec37dc6576b51d1793118dd5ff73f9 100644 (file)
@@ -92,7 +92,7 @@ pub struct InstanceConfig {
   // Ordinary settings:
   pub addrs:                        Vec<IpAddr>,
   pub vnetwork:                     Vec<IpNet>,
-  pub vaddr:                        Vec<IpAddr>,
+  pub vaddr:                        IpAddr,
   pub vrelay:                       IpAddr,
   pub port:                         u16,
   pub mtu:                          u32,
@@ -614,8 +614,48 @@ impl<'c> ResolveContext<'c> {
 
 impl InstanceConfig {
   #[throws(AE)]
-  fn complete(&self) {
-    
+  fn complete(&mut self, end: LinkEnd) {
+    let mut vhosts = self.vnetwork.iter()
+      .map(|n| n.hosts()).flatten()
+      .filter({ let vaddr = self.vaddr; move |v| v != &vaddr });
+
+    if self.vaddr.is_unspecified() {
+      self.vaddr = vhosts.next().ok_or_else(
+        || anyhow!("vnetwork too small to generate vaddrr")
+      )?;
+    }
+    if self.vrelay.is_unspecified() {
+      self.vrelay = vhosts.next().ok_or_else(
+        || anyhow!("vnetwork too small to generate vrelay")
+      )?;
+    }
+
+    match end {
+      LinkEnd::Client => {
+        if &self.url == &default::<Uri>() {
+          let addr = self.addrs.get(0).ok_or_else(
+            || anyhow!("client needs addrs or url set")
+          )?;
+          self.url = format!(
+            "http://{}{}/",
+            match addr {
+              IpAddr::V4(a) => format!("{}", a),
+              IpAddr::V6(a) => format!("[{}]", a),
+            },
+            match self.port {
+              80 => format!(""),
+              p => format!(":{}", p),
+            })
+            .parse().unwrap()
+        }
+      },
+
+      LinkEnd::Server => {
+        if self.addrs.is_empty() {
+          throw!(anyhow!("missing 'addrs' setting"))
+        }
+      },
+    }
   }
 }
 
@@ -662,10 +702,10 @@ pub fn read(end: LinkEnd) -> Vec<InstanceConfig> {
       ],
     };
 
-    let ic = InstanceConfig::resolve_instance(&rctx)
+    let mut ic = InstanceConfig::resolve_instance(&rctx)
       .with_context(|| format!(r#"resolve config for "{:?}""#, &link))?;
 
-    ic.complete()
+    ic.complete(end)
       .with_context(|| format!(r#"complete config for "{:?}""#, &link))?;
 
     ics.push(ic);