sb-mesh 0.1.1

S&B Sovereign Mesh (sb-mesh) — User-Space P2P Overlay Network, WireGuard-compatible Crypto & TUI
Documentation
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MeshConfig {
    pub listen_port: u16,
    pub air_gap_killswitch: bool,
    pub lan_discovery: bool,
    pub keepalive_secs: u64,
    pub overlay_subnet: String,
    #[serde(default = "default_true")]
    pub traffic_obfuscation: bool,
    #[serde(default = "default_true")]
    pub relay_enabled: bool,
    #[serde(default)]
    pub advertised_subnets: Vec<String>,
    #[serde(default)]
    pub is_exit_node: bool,
    #[serde(default)]
    pub exit_node: Option<String>,
}

fn default_true() -> bool {
    true
}

impl Default for MeshConfig {
    fn default() -> Self {
        Self {
            listen_port: 58888,
            air_gap_killswitch: false,
            lan_discovery: true,
            keepalive_secs: 25,
            overlay_subnet: "10.240.0.0/16".to_string(),
            traffic_obfuscation: true,
            relay_enabled: true,
            advertised_subnets: Vec::new(),
            is_exit_node: false,
            exit_node: None,
        }
    }
}

impl MeshConfig {
    pub fn load_or_default(path: &Path) -> Self {
        if path.exists() {
            if let Ok(content) = fs::read_to_string(path) {
                if let Ok(cfg) = toml::from_str::<MeshConfig>(&content) {
                    return cfg;
                }
            }
        }
        let default_cfg = Self::default();
        let _ = default_cfg.save(path);
        default_cfg
    }

    pub fn save(&self, path: &Path) -> Result<(), String> {
        let content = toml::to_string_pretty(self)
            .map_err(|e| format!("Failed to serialize config: {}", e))?;
        fs::write(path, content)
            .map_err(|e| format!("Failed to write config: {}", e))?;
        Ok(())
    }
}