client, server: make adding routes optional (#71)
parent
46f2a1e24c
commit
170c8267bf
|
@ -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)?,
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)?;
|
||||||
|
if do_routing {
|
||||||
add_route(interface, address)?;
|
add_route(interface, address)?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue