Skip to content

Commit

Permalink
feat: add configuration for derp regions
Browse files Browse the repository at this point in the history
* feat: add configuration for derp regions

* add comment
  • Loading branch information
dignifiedquire authored May 12, 2023
1 parent 1422fb1 commit 96903e7
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target
iroh.config.toml
50 changes: 49 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ base64 = "0.21.0"
blake3 = "1.3.3"
bytes = { version = "1.4", features = ["serde"] }
clap = { version = "4", features = ["derive"], optional = true }
config = { version = "0.13.1", default-features = false, features = ["toml", "preserve_order"] }
console = { version = "0.15.5", optional = true }
crypto_box = { version = "0.9.0-pre", features = ["serde", "chacha20"] }
curve25519-dalek = "=4.0.0-rc.2"
Expand Down
16 changes: 16 additions & 0 deletions example.config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[[derp_regions]]
region_id = 1
avoid = false
region_code = "default"


[[derp_regions.nodes]]
name = "default-1"
region_id = 1
host_name = "foo.bar"
stun_only = false
stun_port = 1244
ipv4 = { Some = "127.0.0.1" }
ipv6 = "None"
derp_port = 1

130 changes: 130 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
//! Configuration for the iroh CLI.

use std::{collections::HashMap, path::Path};

use anyhow::Result;
use config::{Environment, File, Value};
use serde::{Deserialize, Serialize};
use tracing::debug;

use crate::hp::derp::{DerpMap, DerpNode, DerpRegion, UseIpv4, UseIpv6};

/// CONFIG_FILE_NAME is the name of the optional config file located in the iroh home directory
pub const CONFIG_FILE_NAME: &str = "iroh.config.toml";
/// ENV_PREFIX should be used along side the config field name to set a config field using
/// environment variables
/// For example, `IROH_PATH=/path/to/config` would set the value of the `Config.path` field
pub const ENV_PREFIX: &str = "IROH";

/// The configuration for the iroh cli.
#[derive(PartialEq, Eq, Debug, Deserialize, Serialize, Clone)]
#[serde(default)]
pub struct Config {
/// The regions for DERP to use.
pub derp_regions: Vec<DerpRegion>,
}

impl Default for Config {
fn default() -> Self {
Self {
derp_regions: vec![default_derp_region()],
}
}
}

impl Config {
/// Make a config using a default, files, environment variables, and commandline flags.
///
/// Later items in the *file_paths* slice will have a higher priority than earlier ones.
///
/// Environment variables are expected to start with the *env_prefix*. Nested fields can be
/// accessed using `.`, if your environment allows env vars with `.`
///
/// Note: For the metrics configuration env vars, it is recommended to use the metrics
/// specific prefix `IROH_METRICS` to set a field in the metrics config. You can use the
/// above dot notation to set a metrics field, eg, `IROH_CONFIG_METRICS.SERVICE_NAME`, but
/// only if your environment allows it
pub fn load<S, V>(
file_paths: &[Option<&Path>],
env_prefix: &str,
flag_overrides: HashMap<S, V>,
) -> Result<Config>
where
S: AsRef<str>,
V: Into<Value>,
{
let mut builder = config::Config::builder();

// layer on config options from files
for path in file_paths.iter().flatten() {
if path.exists() {
let p = path.to_str().ok_or_else(|| anyhow::anyhow!("empty path"))?;
builder = builder.add_source(File::with_name(p));
}
}

// next, add any environment variables
builder = builder.add_source(
Environment::with_prefix(env_prefix)
.separator("__")
.try_parsing(true),
);

// finally, override any values
for (flag, val) in flag_overrides.into_iter() {
builder = builder.set_override(flag, val)?;
}

let cfg = builder.build()?;
debug!("make_config:\n{:#?}\n", cfg);
let cfg = cfg.try_deserialize()?;
Ok(cfg)
}

/// Constructs a `DerpMap` based on the current configuration.
pub fn derp_map(&self) -> Option<DerpMap> {
if self.derp_regions.is_empty() {
return None;
}

let mut regions = HashMap::new();
for region in &self.derp_regions {
regions.insert(region.region_id, region.clone());
}

Some(DerpMap { regions })
}
}

fn default_derp_region() -> DerpRegion {
// The default derper run by number0.
let default_n0_derp = DerpNode {
name: "default-1".into(),
region_id: 1,
host_name: "derp.iroh.computer".into(),
stun_only: false,
stun_port: 3478,
ipv4: UseIpv4::Some("35.175.99.113".parse().unwrap()),
ipv6: UseIpv6::None,
derp_port: 3340,
stun_test_ip: None,
};
DerpRegion {
region_id: 1,
nodes: vec![default_n0_derp],
avoid: false,
region_code: "default-1".into(),
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_default_settings() {
let config = Config::load::<String, String>(&[][..], "__FOO", Default::default()).unwrap();

assert_eq!(config.derp_regions.len(), 1);
}
}
10 changes: 6 additions & 4 deletions src/hp/derp/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use std::{
net::{IpAddr, Ipv4Addr, Ipv6Addr},
};

use serde::{Deserialize, Serialize};

#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct DerpMap {
pub regions: HashMap<usize, DerpRegion>,
Expand Down Expand Up @@ -54,7 +56,7 @@ impl DerpMap {
}

/// A geographic region running DERP relay node(s).
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DerpRegion {
/// A unique integer for a geographic region.
pub region_id: usize,
Expand All @@ -63,7 +65,7 @@ pub struct DerpRegion {
pub region_code: String,
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DerpNode {
pub name: String,
pub region_id: usize,
Expand All @@ -82,7 +84,7 @@ pub struct DerpNode {
pub derp_port: u16,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum UseIpv4 {
None,
Disabled,
Expand All @@ -96,7 +98,7 @@ impl UseIpv4 {
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum UseIpv6 {
None,
Disabled,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// #![deny(missing_docs)] TODO: fix me before merging
#![deny(rustdoc::broken_intra_doc_links)]
pub mod blobs;
pub mod config;
pub mod get;
pub mod main_util;
pub mod metrics;
Expand Down
Loading

0 comments on commit 96903e7

Please sign in to comment.