client, server: make adding routes optional (#71)

pull/79/head
Johann150 2021-05-11 19:31:47 +02:00 committed by GitHub
parent 46f2a1e24c
commit 170c8267bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 13 deletions

View File

@ -5,7 +5,8 @@ use indoc::printdoc;
use shared::{ use shared::{
interface_config::InterfaceConfig, prompts, AddAssociationOpts, AddCidrOpts, AddPeerOpts, interface_config::InterfaceConfig, prompts, AddAssociationOpts, AddCidrOpts, AddPeerOpts,
Association, AssociationContents, Cidr, CidrTree, EndpointContents, InstallOpts, Interface, Association, AssociationContents, Cidr, CidrTree, EndpointContents, InstallOpts, Interface,
IoErrorContext, Peer, RedeemContents, State, CLIENT_CONFIG_PATH, REDEEM_TRANSITION_WAIT, IoErrorContext, Peer, RedeemContents, RoutingOpt, State, CLIENT_CONFIG_PATH,
REDEEM_TRANSITION_WAIT,
}; };
use std::{ use std::{
fmt, fmt,
@ -72,6 +73,9 @@ enum Command {
#[structopt(flatten)] #[structopt(flatten)]
opts: InstallOpts, opts: InstallOpts,
#[structopt(flatten)]
routing: RoutingOpt,
}, },
/// Enumerate all innernet connections. /// Enumerate all innernet connections.
@ -103,6 +107,9 @@ enum Command {
#[structopt(flatten)] #[structopt(flatten)]
hosts: HostsOpt, hosts: HostsOpt,
#[structopt(flatten)]
routing: RoutingOpt,
interface: Interface, interface: Interface,
}, },
@ -112,12 +119,15 @@ enum Command {
#[structopt(flatten)] #[structopt(flatten)]
hosts: HostsOpt, hosts: HostsOpt,
#[structopt(flatten)]
routing: RoutingOpt,
}, },
/// Uninstall an innernet network. /// Uninstall an innernet network.
Uninstall { interface: Interface }, Uninstall { interface: Interface },
/// Bring down the interface (equivalent to "wg-quick down [interface]") /// Bring down the interface (equivalent to "wg-quick down <interface>")
Down { interface: Interface }, Down { interface: Interface },
/// Add a new peer. /// Add a new peer.
@ -219,7 +229,12 @@ fn update_hosts_file(
Ok(()) Ok(())
} }
fn install(invite: &Path, hosts_file: Option<PathBuf>, opts: InstallOpts) -> Result<(), Error> { fn install(
invite: &Path,
hosts_file: Option<PathBuf>,
opts: InstallOpts,
routing: RoutingOpt,
) -> Result<(), Error> {
shared::ensure_dirs_exist(&[*CLIENT_CONFIG_PATH])?; shared::ensure_dirs_exist(&[*CLIENT_CONFIG_PATH])?;
let config = InterfaceConfig::from_file(invite)?; let config = InterfaceConfig::from_file(invite)?;
@ -240,7 +255,7 @@ fn install(invite: &Path, hosts_file: Option<PathBuf>, opts: InstallOpts) -> Res
} }
let iface = iface.parse()?; let iface = iface.parse()?;
redeem_invite(&iface, config, target_conf).map_err(|e| { redeem_invite(&iface, config, target_conf, routing).map_err(|e| {
println!("{} bringing down the interface.", "[*]".dimmed()); println!("{} bringing down the interface.", "[*]".dimmed());
if let Err(e) = wg::down(&iface) { if let Err(e) = wg::down(&iface) {
println!("{} failed to bring down interface: {}.", "[*]".yellow(), e.to_string()); println!("{} failed to bring down interface: {}.", "[*]".yellow(), e.to_string());
@ -251,7 +266,7 @@ fn install(invite: &Path, hosts_file: Option<PathBuf>, opts: InstallOpts) -> Res
let mut fetch_success = false; let mut fetch_success = false;
for _ in 0..3 { for _ in 0..3 {
if fetch(&iface, false, hosts_file.clone()).is_ok() { if fetch(&iface, false, hosts_file.clone(), routing).is_ok() {
fetch_success = true; fetch_success = true;
break; break;
} }
@ -305,6 +320,7 @@ fn redeem_invite(
iface: &InterfaceName, iface: &InterfaceName,
mut config: InterfaceConfig, mut config: InterfaceConfig,
target_conf: PathBuf, target_conf: PathBuf,
routing: RoutingOpt,
) -> Result<(), Error> { ) -> Result<(), Error> {
println!("{} bringing up the interface.", "[*]".dimmed()); println!("{} bringing up the interface.", "[*]".dimmed());
let resolved_endpoint = config.server.external_endpoint.resolve()?; let resolved_endpoint = config.server.external_endpoint.resolve()?;
@ -318,6 +334,7 @@ fn redeem_invite(
config.server.internal_endpoint.ip(), config.server.internal_endpoint.ip(),
resolved_endpoint, resolved_endpoint,
)), )),
!routing.no_routing,
)?; )?;
println!("{} Generating new keypair.", "[*]".dimmed()); println!("{} Generating new keypair.", "[*]".dimmed());
@ -360,9 +377,10 @@ fn up(
interface: &InterfaceName, interface: &InterfaceName,
loop_interval: Option<Duration>, loop_interval: Option<Duration>,
hosts_path: Option<PathBuf>, hosts_path: Option<PathBuf>,
routing: RoutingOpt,
) -> Result<(), Error> { ) -> Result<(), Error> {
loop { loop {
fetch(interface, true, hosts_path.clone())?; fetch(interface, true, hosts_path.clone(), routing)?;
match loop_interval { match loop_interval {
Some(interval) => thread::sleep(interval), Some(interval) => thread::sleep(interval),
None => break, None => break,
@ -376,6 +394,7 @@ fn fetch(
interface: &InterfaceName, interface: &InterfaceName,
bring_up_interface: bool, bring_up_interface: bool,
hosts_path: Option<PathBuf>, hosts_path: Option<PathBuf>,
routing: RoutingOpt,
) -> Result<(), Error> { ) -> Result<(), Error> {
let config = InterfaceConfig::from_interface(interface)?; let config = InterfaceConfig::from_interface(interface)?;
let interface_up = if let Ok(interfaces) = DeviceInfo::enumerate() { let interface_up = if let Ok(interfaces) = DeviceInfo::enumerate() {
@ -405,6 +424,7 @@ fn fetch(
config.server.internal_endpoint.ip(), config.server.internal_endpoint.ip(),
resolved_endpoint, resolved_endpoint,
)), )),
!routing.no_routing,
)? )?
} }
@ -910,22 +930,29 @@ fn run(opt: Opts) -> Result<(), Error> {
invite, invite,
hosts, hosts,
opts, opts,
} => install(&invite, hosts.into(), opts)?, routing,
} => install(&invite, hosts.into(), opts, routing)?,
Command::Show { Command::Show {
short, short,
tree, tree,
interface, interface,
} => show(short, tree, interface)?, } => show(short, tree, interface)?,
Command::Fetch { interface, hosts } => fetch(&interface, false, hosts.into())?, Command::Fetch {
interface,
hosts,
routing,
} => fetch(&interface, false, hosts.into(), routing)?,
Command::Up { Command::Up {
interface, interface,
daemon, daemon,
hosts, hosts,
routing,
interval, interval,
} => up( } => up(
&interface, &interface,
daemon.then(|| Duration::from_secs(interval)), daemon.then(|| Duration::from_secs(interval)),
hosts.into(), hosts.into(),
routing,
)?, )?,
Command::Down { interface } => wg::down(&interface)?, Command::Down { interface } => wg::down(&interface)?,
Command::Uninstall { interface } => uninstall(&interface)?, Command::Uninstall { interface } => uninstall(&interface)?,

View File

@ -6,7 +6,7 @@ use ipnetwork::IpNetwork;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use rusqlite::Connection; use rusqlite::Connection;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use shared::{AddCidrOpts, AddPeerOpts, IoErrorContext, INNERNET_PUBKEY_HEADER}; use shared::{AddCidrOpts, AddPeerOpts, IoErrorContext, RoutingOpt, INNERNET_PUBKEY_HEADER};
use std::{ use std::{
collections::{HashMap, VecDeque}, collections::{HashMap, VecDeque},
convert::TryInto, convert::TryInto,
@ -60,7 +60,12 @@ enum Command {
Uninstall { interface: Interface }, Uninstall { interface: Interface },
/// Serve the coordinating server for an existing network. /// Serve the coordinating server for an existing network.
Serve { interface: Interface }, Serve {
interface: Interface,
#[structopt(flatten)]
routing: RoutingOpt,
},
/// Add a peer to an existing network. /// Add a peer to an existing network.
AddPeer { AddPeer {
@ -206,7 +211,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
} }
Command::Uninstall { interface } => uninstall(&interface, &conf)?, Command::Uninstall { interface } => uninstall(&interface, &conf)?,
Command::Serve { interface } => serve(*interface, &conf).await?, Command::Serve { interface, routing } => serve(*interface, &conf, routing).await?,
Command::AddPeer { interface, args } => add_peer(&interface, &conf, args)?, Command::AddPeer { interface, args } => add_peer(&interface, &conf, args)?,
Command::AddCidr { interface, args } => add_cidr(&interface, &conf, args)?, Command::AddCidr { interface, args } => add_cidr(&interface, &conf, args)?,
} }
@ -370,7 +375,11 @@ fn spawn_expired_invite_sweeper(db: Db) {
}); });
} }
async fn serve(interface: InterfaceName, conf: &ServerConfig) -> Result<(), Error> { async fn serve(
interface: InterfaceName,
conf: &ServerConfig,
routing: RoutingOpt,
) -> Result<(), Error> {
let config = ConfigFile::from_file(conf.config_path(&interface))?; let config = ConfigFile::from_file(conf.config_path(&interface))?;
let conn = open_database_connection(&interface, conf)?; let conn = open_database_connection(&interface, conf)?;
@ -387,6 +396,7 @@ async fn serve(interface: InterfaceName, conf: &ServerConfig) -> Result<(), Erro
IpNetwork::new(config.address, config.network_cidr_prefix)?, IpNetwork::new(config.address, config.network_cidr_prefix)?,
Some(config.listen_port), Some(config.listen_port),
None, None,
!routing.no_routing,
)?; )?;
DeviceConfigBuilder::new() DeviceConfigBuilder::new()

View File

@ -346,6 +346,14 @@ pub struct AddAssociationOpts {
pub cidr2: Option<String>, pub cidr2: Option<String>,
} }
#[derive(Debug, Clone, Copy, StructOpt)]
pub struct RoutingOpt {
#[structopt(long)]
/// Whether the routing should be done by innernet or is done by an
/// external tool like e.g. babeld.
pub no_routing: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct PeerContents { pub struct PeerContents {
pub name: Hostname, pub name: Hostname,

View File

@ -67,6 +67,7 @@ pub fn up(
address: IpNetwork, address: IpNetwork,
listen_port: Option<u16>, listen_port: Option<u16>,
peer: Option<(&str, IpAddr, SocketAddr)>, peer: Option<(&str, IpAddr, SocketAddr)>,
do_routing: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut device = DeviceConfigBuilder::new(); let mut device = DeviceConfigBuilder::new();
if let Some((public_key, address, endpoint)) = peer { if let Some((public_key, address, endpoint)) = peer {
@ -83,7 +84,9 @@ pub fn up(
.set_private_key(wgctrl::Key::from_base64(&private_key).unwrap()) .set_private_key(wgctrl::Key::from_base64(&private_key).unwrap())
.apply(interface)?; .apply(interface)?;
set_addr(interface, address)?; set_addr(interface, address)?;
add_route(interface, address)?; if do_routing {
add_route(interface, address)?;
}
Ok(()) Ok(())
} }