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::{
interface_config::InterfaceConfig, prompts, AddAssociationOpts, AddCidrOpts, AddPeerOpts,
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::{
fmt,
@ -72,6 +73,9 @@ enum Command {
#[structopt(flatten)]
opts: InstallOpts,
#[structopt(flatten)]
routing: RoutingOpt,
},
/// Enumerate all innernet connections.
@ -103,6 +107,9 @@ enum Command {
#[structopt(flatten)]
hosts: HostsOpt,
#[structopt(flatten)]
routing: RoutingOpt,
interface: Interface,
},
@ -112,12 +119,15 @@ enum Command {
#[structopt(flatten)]
hosts: HostsOpt,
#[structopt(flatten)]
routing: RoutingOpt,
},
/// Uninstall an innernet network.
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 },
/// Add a new peer.
@ -219,7 +229,12 @@ fn update_hosts_file(
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])?;
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()?;
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());
if let Err(e) = wg::down(&iface) {
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;
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;
break;
}
@ -305,6 +320,7 @@ fn redeem_invite(
iface: &InterfaceName,
mut config: InterfaceConfig,
target_conf: PathBuf,
routing: RoutingOpt,
) -> Result<(), Error> {
println!("{} bringing up the interface.", "[*]".dimmed());
let resolved_endpoint = config.server.external_endpoint.resolve()?;
@ -318,6 +334,7 @@ fn redeem_invite(
config.server.internal_endpoint.ip(),
resolved_endpoint,
)),
!routing.no_routing,
)?;
println!("{} Generating new keypair.", "[*]".dimmed());
@ -360,9 +377,10 @@ fn up(
interface: &InterfaceName,
loop_interval: Option<Duration>,
hosts_path: Option<PathBuf>,
routing: RoutingOpt,
) -> Result<(), Error> {
loop {
fetch(interface, true, hosts_path.clone())?;
fetch(interface, true, hosts_path.clone(), routing)?;
match loop_interval {
Some(interval) => thread::sleep(interval),
None => break,
@ -376,6 +394,7 @@ fn fetch(
interface: &InterfaceName,
bring_up_interface: bool,
hosts_path: Option<PathBuf>,
routing: RoutingOpt,
) -> Result<(), Error> {
let config = InterfaceConfig::from_interface(interface)?;
let interface_up = if let Ok(interfaces) = DeviceInfo::enumerate() {
@ -405,6 +424,7 @@ fn fetch(
config.server.internal_endpoint.ip(),
resolved_endpoint,
)),
!routing.no_routing,
)?
}
@ -910,22 +930,29 @@ fn run(opt: Opts) -> Result<(), Error> {
invite,
hosts,
opts,
} => install(&invite, hosts.into(), opts)?,
routing,
} => install(&invite, hosts.into(), opts, routing)?,
Command::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 {
interface,
daemon,
hosts,
routing,
interval,
} => up(
&interface,
daemon.then(|| Duration::from_secs(interval)),
hosts.into(),
routing,
)?,
Command::Down { interface } => wg::down(&interface)?,
Command::Uninstall { interface } => uninstall(&interface)?,

View File

@ -6,7 +6,7 @@ use ipnetwork::IpNetwork;
use parking_lot::{Mutex, RwLock};
use rusqlite::Connection;
use serde::{Deserialize, Serialize};
use shared::{AddCidrOpts, AddPeerOpts, IoErrorContext, INNERNET_PUBKEY_HEADER};
use shared::{AddCidrOpts, AddPeerOpts, IoErrorContext, RoutingOpt, INNERNET_PUBKEY_HEADER};
use std::{
collections::{HashMap, VecDeque},
convert::TryInto,
@ -60,7 +60,12 @@ enum Command {
Uninstall { interface: Interface },
/// 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.
AddPeer {
@ -206,7 +211,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}
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::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 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)?,
Some(config.listen_port),
None,
!routing.no_routing,
)?;
DeviceConfigBuilder::new()

View File

@ -346,6 +346,14 @@ pub struct AddAssociationOpts {
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)]
pub struct PeerContents {
pub name: Hostname,

View File

@ -67,6 +67,7 @@ pub fn up(
address: IpNetwork,
listen_port: Option<u16>,
peer: Option<(&str, IpAddr, SocketAddr)>,
do_routing: bool,
) -> Result<(), Error> {
let mut device = DeviceConfigBuilder::new();
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())
.apply(interface)?;
set_addr(interface, address)?;
add_route(interface, address)?;
if do_routing {
add_route(interface, address)?;
}
Ok(())
}