meta: switch from ipnetwork to ipnet (#193)
parent
b6ce16bc00
commit
a77cbb4f49
|
@ -137,7 +137,7 @@ dependencies = [
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"hostsfile",
|
"hostsfile",
|
||||||
"indoc",
|
"indoc",
|
||||||
"ipnetwork",
|
"ipnet",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -470,9 +470,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnetwork"
|
name = "ipnet"
|
||||||
version = "0.17.0"
|
version = "2.3.1"
|
||||||
source = "git+https://github.com/mcginty/ipnetwork?rev=393f2d89e41ac6c1c0d80a31fc0997c387a7f7ba#393f2d89e41ac6c1c0d80a31fc0997c387a7f7ba"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -933,7 +934,7 @@ dependencies = [
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"hyper",
|
"hyper",
|
||||||
"indoc",
|
"indoc",
|
||||||
"ipnetwork",
|
"ipnet",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"libsqlite3-sys",
|
"libsqlite3-sys",
|
||||||
|
@ -966,7 +967,7 @@ dependencies = [
|
||||||
"colored",
|
"colored",
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"indoc",
|
"indoc",
|
||||||
"ipnetwork",
|
"ipnet",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -21,7 +21,7 @@ clap_complete = "3"
|
||||||
dialoguer = { version = "0.9", default-features = false }
|
dialoguer = { version = "0.9", default-features = false }
|
||||||
hostsfile = { path = "../hostsfile" }
|
hostsfile = { path = "../hostsfile" }
|
||||||
indoc = "1"
|
indoc = "1"
|
||||||
ipnetwork = { git = "https://github.com/mcginty/ipnetwork", rev = "393f2d89e41ac6c1c0d80a31fc0997c387a7f7ba" }
|
ipnet = { version = "2", features = ["serde"] }
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
regex = { version = "1", default-features = false, features = ["std"] }
|
regex = { version = "1", default-features = false, features = ["std"] }
|
||||||
|
|
|
@ -24,7 +24,7 @@ colored = "2"
|
||||||
dialoguer = { version = "0.9", default-features = false }
|
dialoguer = { version = "0.9", default-features = false }
|
||||||
hyper = { version = "0.14", default-features = false, features = ["http1", "server", "runtime", "stream"] }
|
hyper = { version = "0.14", default-features = false, features = ["http1", "server", "runtime", "stream"] }
|
||||||
indoc = "1"
|
indoc = "1"
|
||||||
ipnetwork = { git = "https://github.com/mcginty/ipnetwork", rev = "393f2d89e41ac6c1c0d80a31fc0997c387a7f7ba" }
|
ipnet = { version = "2", features = ["serde"] }
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
libsqlite3-sys = "0.23"
|
libsqlite3-sys = "0.23"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::ServerError;
|
use crate::ServerError;
|
||||||
use ipnetwork::IpNetwork;
|
use ipnet::IpNet;
|
||||||
use rusqlite::{params, Connection};
|
use rusqlite::{params, Connection};
|
||||||
use shared::{Cidr, CidrContents};
|
use shared::{Cidr, CidrContents, IpNetExt};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
pub static CREATE_TABLE_SQL: &str = "CREATE TABLE cidrs (
|
pub static CREATE_TABLE_SQL: &str = "CREATE TABLE cidrs (
|
||||||
|
@ -56,8 +56,8 @@ impl DatabaseCidr {
|
||||||
|
|
||||||
let closest_parent = cidrs
|
let closest_parent = cidrs
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|current| cidr.is_subnet_of(current.cidr))
|
.filter(|current| current.cidr.contains(cidr))
|
||||||
.max_by_key(|current| current.cidr.prefix());
|
.max_by_key(|current| current.cidr.prefix_len());
|
||||||
|
|
||||||
if let Some(closest_parent) = closest_parent {
|
if let Some(closest_parent) = closest_parent {
|
||||||
if closest_parent.id != *parent_id {
|
if closest_parent.id != *parent_id {
|
||||||
|
@ -70,7 +70,7 @@ impl DatabaseCidr {
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent_cidr = Self::get(conn, *parent_id)?.cidr;
|
let parent_cidr = Self::get(conn, *parent_id)?.cidr;
|
||||||
if !parent_cidr.contains(cidr.network()) || !parent_cidr.contains(cidr.broadcast()) {
|
if !parent_cidr.contains(&cidr.network()) || !parent_cidr.contains(&cidr.broadcast()) {
|
||||||
log::warn!("tried to add a CIDR with a network range outside of its parent.");
|
log::warn!("tried to add a CIDR with a network range outside of its parent.");
|
||||||
return Err(ServerError::InvalidQuery);
|
return Err(ServerError::InvalidQuery);
|
||||||
}
|
}
|
||||||
|
@ -81,10 +81,10 @@ impl DatabaseCidr {
|
||||||
.filter(|current| current.parent == *parent)
|
.filter(|current| current.parent == *parent)
|
||||||
.map(|sibling| sibling.cidr)
|
.map(|sibling| sibling.cidr)
|
||||||
.any(|sibling| {
|
.any(|sibling| {
|
||||||
cidr.contains(sibling.network())
|
cidr.contains(&sibling.network())
|
||||||
|| cidr.contains(sibling.broadcast())
|
|| cidr.contains(&sibling.broadcast())
|
||||||
|| sibling.contains(cidr.network())
|
|| sibling.contains(&cidr.network())
|
||||||
|| sibling.contains(cidr.broadcast())
|
|| sibling.contains(&cidr.broadcast())
|
||||||
});
|
});
|
||||||
|
|
||||||
if overlapping_sibling {
|
if overlapping_sibling {
|
||||||
|
@ -95,7 +95,12 @@ impl DatabaseCidr {
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"INSERT INTO cidrs (name, ip, prefix, parent)
|
"INSERT INTO cidrs (name, ip, prefix, parent)
|
||||||
VALUES (?1, ?2, ?3, ?4)",
|
VALUES (?1, ?2, ?3, ?4)",
|
||||||
params![name, cidr.ip().to_string(), cidr.prefix() as i32, parent],
|
params![
|
||||||
|
name,
|
||||||
|
cidr.addr().to_string(),
|
||||||
|
cidr.prefix_len() as i32,
|
||||||
|
parent
|
||||||
|
],
|
||||||
)?;
|
)?;
|
||||||
let id = conn.last_insert_rowid();
|
let id = conn.last_insert_rowid();
|
||||||
Ok(Cidr { id, contents })
|
Ok(Cidr { id, contents })
|
||||||
|
@ -109,14 +114,12 @@ impl DatabaseCidr {
|
||||||
fn from_row(row: &rusqlite::Row) -> Result<Cidr, rusqlite::Error> {
|
fn from_row(row: &rusqlite::Row) -> Result<Cidr, rusqlite::Error> {
|
||||||
let id = row.get(0)?;
|
let id = row.get(0)?;
|
||||||
let name = row.get(1)?;
|
let name = row.get(1)?;
|
||||||
let ip: String = row.get(2)?;
|
let ip_str: String = row.get(2)?;
|
||||||
let prefix = row.get(3)?;
|
let prefix = row.get(3)?;
|
||||||
let cidr = IpNetwork::new(
|
let ip = ip_str
|
||||||
ip.parse()
|
.parse()
|
||||||
.map_err(|_| rusqlite::Error::ExecuteReturnedResults)?,
|
.map_err(|_| rusqlite::Error::ExecuteReturnedResults)?;
|
||||||
prefix,
|
let cidr = IpNet::new(ip, prefix).map_err(|_| rusqlite::Error::ExecuteReturnedResults)?;
|
||||||
)
|
|
||||||
.map_err(|_| rusqlite::Error::ExecuteReturnedResults)?;
|
|
||||||
let parent = row.get(4)?;
|
let parent = row.get(4)?;
|
||||||
Ok(Cidr {
|
Ok(Cidr {
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::ServerError;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rusqlite::{params, types::Type, Connection};
|
use rusqlite::{params, types::Type, Connection};
|
||||||
use shared::{Peer, PeerContents, PERSISTENT_KEEPALIVE_INTERVAL_SECS};
|
use shared::{IpNetExt, Peer, PeerContents, PERSISTENT_KEEPALIVE_INTERVAL_SECS};
|
||||||
use std::{
|
use std::{
|
||||||
net::IpAddr,
|
net::IpAddr,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
|
@ -96,12 +96,12 @@ impl DatabasePeer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let cidr = DatabaseCidr::get(conn, *cidr_id)?;
|
let cidr = DatabaseCidr::get(conn, *cidr_id)?;
|
||||||
if !cidr.cidr.contains(*ip) {
|
if !cidr.cidr.contains(ip) {
|
||||||
log::warn!("tried to add peer with IP outside of parent CIDR range.");
|
log::warn!("tried to add peer with IP outside of parent CIDR range.");
|
||||||
return Err(ServerError::InvalidQuery);
|
return Err(ServerError::InvalidQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cidr.cidr.is_assignable(*ip) {
|
if !cidr.cidr.is_assignable(ip) {
|
||||||
println!(
|
println!(
|
||||||
"Peer IP {} is not unicast assignable in CIDR {}",
|
"Peer IP {} is not unicast assignable in CIDR {}",
|
||||||
ip, cidr.cidr
|
ip, cidr.cidr
|
||||||
|
|
|
@ -4,9 +4,12 @@ use clap::Parser;
|
||||||
use db::DatabaseCidr;
|
use db::DatabaseCidr;
|
||||||
use dialoguer::{theme::ColorfulTheme, Input};
|
use dialoguer::{theme::ColorfulTheme, Input};
|
||||||
use indoc::printdoc;
|
use indoc::printdoc;
|
||||||
|
use ipnet::IpNet;
|
||||||
use publicip::Preference;
|
use publicip::Preference;
|
||||||
use rusqlite::{params, Connection};
|
use rusqlite::{params, Connection};
|
||||||
use shared::{prompts, CidrContents, Endpoint, PeerContents, PERSISTENT_KEEPALIVE_INTERVAL_SECS};
|
use shared::{
|
||||||
|
prompts, CidrContents, Endpoint, IpNetExt, PeerContents, PERSISTENT_KEEPALIVE_INTERVAL_SECS,
|
||||||
|
};
|
||||||
use wireguard_control::KeyPair;
|
use wireguard_control::KeyPair;
|
||||||
|
|
||||||
fn create_database<P: AsRef<Path>>(
|
fn create_database<P: AsRef<Path>>(
|
||||||
|
@ -31,7 +34,7 @@ pub struct InitializeOpts {
|
||||||
|
|
||||||
/// The network CIDR (ex: 10.42.0.0/16)
|
/// The network CIDR (ex: 10.42.0.0/16)
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub network_cidr: Option<IpNetwork>,
|
pub network_cidr: Option<IpNet>,
|
||||||
|
|
||||||
/// This server's external endpoint (ex: 100.100.100.100:51820)
|
/// This server's external endpoint (ex: 100.100.100.100:51820)
|
||||||
#[clap(long, conflicts_with = "auto-external-endpoint")]
|
#[clap(long, conflicts_with = "auto-external-endpoint")]
|
||||||
|
@ -48,8 +51,8 @@ pub struct InitializeOpts {
|
||||||
|
|
||||||
struct DbInitData {
|
struct DbInitData {
|
||||||
network_name: String,
|
network_name: String,
|
||||||
network_cidr: IpNetwork,
|
network_cidr: IpNet,
|
||||||
server_cidr: IpNetwork,
|
server_cidr: IpNet,
|
||||||
our_ip: IpAddr,
|
our_ip: IpAddr,
|
||||||
public_key_base64: String,
|
public_key_base64: String,
|
||||||
endpoint: Endpoint,
|
endpoint: Endpoint,
|
||||||
|
@ -131,7 +134,7 @@ pub fn init_wizard(conf: &ServerConfig, opts: InitializeOpts) -> Result<(), Erro
|
||||||
.interact()?
|
.interact()?
|
||||||
};
|
};
|
||||||
|
|
||||||
let root_cidr: IpNetwork = if let Some(cidr) = opts.network_cidr {
|
let root_cidr: IpNet = if let Some(cidr) = opts.network_cidr {
|
||||||
cidr
|
cidr
|
||||||
} else {
|
} else {
|
||||||
Input::with_theme(&theme)
|
Input::with_theme(&theme)
|
||||||
|
@ -163,10 +166,9 @@ pub fn init_wizard(conf: &ServerConfig, opts: InitializeOpts) -> Result<(), Erro
|
||||||
};
|
};
|
||||||
|
|
||||||
let our_ip = root_cidr
|
let our_ip = root_cidr
|
||||||
.iter()
|
.hosts()
|
||||||
.find(|ip| root_cidr.is_assignable(*ip))
|
.find(|ip| root_cidr.is_assignable(ip))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let server_cidr = IpNetwork::new(our_ip, root_cidr.max_prefix())?;
|
|
||||||
let config_path = conf.config_path(&name);
|
let config_path = conf.config_path(&name);
|
||||||
let our_keypair = KeyPair::generate();
|
let our_keypair = KeyPair::generate();
|
||||||
|
|
||||||
|
@ -174,14 +176,14 @@ pub fn init_wizard(conf: &ServerConfig, opts: InitializeOpts) -> Result<(), Erro
|
||||||
private_key: our_keypair.private.to_base64(),
|
private_key: our_keypair.private.to_base64(),
|
||||||
listen_port,
|
listen_port,
|
||||||
address: our_ip,
|
address: our_ip,
|
||||||
network_cidr_prefix: root_cidr.prefix(),
|
network_cidr_prefix: root_cidr.prefix_len(),
|
||||||
};
|
};
|
||||||
config.write_to_path(&config_path)?;
|
config.write_to_path(&config_path)?;
|
||||||
|
|
||||||
let db_init_data = DbInitData {
|
let db_init_data = DbInitData {
|
||||||
network_name: name.to_string(),
|
network_name: name.to_string(),
|
||||||
network_cidr: root_cidr,
|
network_cidr: root_cidr,
|
||||||
server_cidr,
|
server_cidr: IpNet::new(our_ip, root_cidr.max_prefix_len())?,
|
||||||
our_ip,
|
our_ip,
|
||||||
public_key_base64: our_keypair.public.to_base64(),
|
public_key_base64: our_keypair.public.to_base64(),
|
||||||
endpoint,
|
endpoint,
|
||||||
|
|
|
@ -4,12 +4,12 @@ use colored::*;
|
||||||
use dialoguer::Confirm;
|
use dialoguer::Confirm;
|
||||||
use hyper::{http, server::conn::AddrStream, Body, Request, Response};
|
use hyper::{http, server::conn::AddrStream, Body, Request, Response};
|
||||||
use indoc::printdoc;
|
use indoc::printdoc;
|
||||||
use ipnetwork::IpNetwork;
|
use ipnet::IpNet;
|
||||||
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::{
|
use shared::{
|
||||||
get_local_addrs, AddCidrOpts, AddPeerOpts, DeleteCidrOpts, Endpoint, IoErrorContext,
|
get_local_addrs, AddCidrOpts, AddPeerOpts, DeleteCidrOpts, Endpoint, IoErrorContext, IpNetExt,
|
||||||
NetworkOpts, PeerContents, RenamePeerOpts, INNERNET_PUBKEY_HEADER,
|
NetworkOpts, PeerContents, RenamePeerOpts, INNERNET_PUBKEY_HEADER,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -502,7 +502,7 @@ async fn serve(
|
||||||
wg::up(
|
wg::up(
|
||||||
&interface,
|
&interface,
|
||||||
&config.private_key,
|
&config.private_key,
|
||||||
IpNetwork::new(config.address, config.network_cidr_prefix)?,
|
IpNet::new(config.address, config.network_cidr_prefix)?,
|
||||||
Some(config.listen_port),
|
Some(config.listen_port),
|
||||||
None,
|
None,
|
||||||
network,
|
network,
|
||||||
|
|
|
@ -13,7 +13,7 @@ clap = { version = "3", features = ["derive"] }
|
||||||
colored = "2.0"
|
colored = "2.0"
|
||||||
dialoguer = { version = "0.9", default-features = false }
|
dialoguer = { version = "0.9", default-features = false }
|
||||||
indoc = "1"
|
indoc = "1"
|
||||||
ipnetwork = { git = "https://github.com/mcginty/ipnetwork", rev ="393f2d89e41ac6c1c0d80a31fc0997c387a7f7ba" }
|
ipnet = { version = "2", features = ["serde"] }
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{chmod, ensure_dirs_exist, Endpoint, Error, IoErrorContext, WrappedIoError};
|
use crate::{chmod, ensure_dirs_exist, Endpoint, Error, IoErrorContext, WrappedIoError};
|
||||||
use indoc::writedoc;
|
use indoc::writedoc;
|
||||||
use ipnetwork::IpNetwork;
|
use ipnet::IpNet;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
fs::{File, OpenOptions},
|
fs::{File, OpenOptions},
|
||||||
|
@ -28,7 +28,7 @@ pub struct InterfaceInfo {
|
||||||
|
|
||||||
/// The invited peer's internal IP address that's been allocated to it, inside
|
/// The invited peer's internal IP address that's been allocated to it, inside
|
||||||
/// the entire network's CIDR prefix.
|
/// the entire network's CIDR prefix.
|
||||||
pub address: IpNetwork,
|
pub address: IpNet,
|
||||||
|
|
||||||
/// WireGuard private key (base64)
|
/// WireGuard private key (base64)
|
||||||
pub private_key: String,
|
pub private_key: String,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
pub use anyhow::Error;
|
pub use anyhow::Error;
|
||||||
|
use ipnet::{IpNet, Ipv4Net, Ipv6Net, PrefixLenError};
|
||||||
use std::{
|
use std::{
|
||||||
fs::{self, File, Permissions},
|
fs::{self, File, Permissions},
|
||||||
io,
|
io,
|
||||||
|
@ -116,3 +117,29 @@ pub fn get_local_addrs() -> Result<impl Iterator<Item = std::net::IpAddr>, io::E
|
||||||
})
|
})
|
||||||
.take(10))
|
.take(10))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IpNetExt {
|
||||||
|
fn is_assignable(&self, ip: &IpAddr) -> bool;
|
||||||
|
|
||||||
|
#[allow(clippy::new_ret_no_self)]
|
||||||
|
fn new(ip: IpAddr, prefix_len: u8) -> Result<IpNet, PrefixLenError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IpNetExt for IpNet {
|
||||||
|
fn new(ip: IpAddr, prefix_len: u8) -> Result<IpNet, PrefixLenError> {
|
||||||
|
Ok(match ip {
|
||||||
|
IpAddr::V4(a) => Ipv4Net::new(a, prefix_len)?.into(),
|
||||||
|
IpAddr::V6(a) => Ipv6Net::new(a, prefix_len)?.into(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_assignable(&self, ip: &IpAddr) -> bool {
|
||||||
|
self.contains(ip)
|
||||||
|
&& match self {
|
||||||
|
IpNet::V4(_) => {
|
||||||
|
self.prefix_len() >= 31 || (ip != &self.network() && ip != &self.broadcast())
|
||||||
|
},
|
||||||
|
IpNet::V6(_) => self.prefix_len() >= 127 || ip != &self.network(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use ipnetwork::IpNetwork;
|
use ipnet::IpNet;
|
||||||
use netlink_packet_core::{NetlinkMessage, NetlinkPayload, NLM_F_ACK, NLM_F_CREATE, NLM_F_REQUEST};
|
use netlink_packet_core::{NetlinkMessage, NetlinkPayload, NLM_F_ACK, NLM_F_CREATE, NLM_F_REQUEST};
|
||||||
use netlink_packet_route::{
|
use netlink_packet_route::{
|
||||||
address,
|
address,
|
||||||
|
@ -36,11 +36,11 @@ pub fn set_up(interface: &InterfaceName, mtu: u32) -> Result<(), io::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), io::Error> {
|
pub fn set_addr(interface: &InterfaceName, addr: IpNet) -> Result<(), io::Error> {
|
||||||
let index = if_nametoindex(interface)?;
|
let index = if_nametoindex(interface)?;
|
||||||
let (family, nlas) = match addr {
|
let (family, nlas) = match addr {
|
||||||
IpNetwork::V4(network) => {
|
IpNet::V4(network) => {
|
||||||
let addr_bytes = network.ip().octets().to_vec();
|
let addr_bytes = network.addr().octets().to_vec();
|
||||||
(
|
(
|
||||||
AF_INET as u8,
|
AF_INET as u8,
|
||||||
vec![
|
vec![
|
||||||
|
@ -49,16 +49,16 @@ pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), io::Er
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
IpNetwork::V6(network) => (
|
IpNet::V6(network) => (
|
||||||
AF_INET6 as u8,
|
AF_INET6 as u8,
|
||||||
vec![address::Nla::Address(network.ip().octets().to_vec())],
|
vec![address::Nla::Address(network.addr().octets().to_vec())],
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let message = AddressMessage {
|
let message = AddressMessage {
|
||||||
header: AddressHeader {
|
header: AddressHeader {
|
||||||
index,
|
index,
|
||||||
family,
|
family,
|
||||||
prefix_len: addr.prefix(),
|
prefix_len: addr.prefix_len(),
|
||||||
scope: RT_SCOPE_UNIVERSE,
|
scope: RT_SCOPE_UNIVERSE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
@ -72,11 +72,11 @@ pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), io::Er
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result<bool, io::Error> {
|
pub fn add_route(interface: &InterfaceName, cidr: IpNet) -> Result<bool, io::Error> {
|
||||||
let if_index = if_nametoindex(interface)?;
|
let if_index = if_nametoindex(interface)?;
|
||||||
let (address_family, dst) = match cidr {
|
let (address_family, dst) = match cidr {
|
||||||
IpNetwork::V4(network) => (AF_INET as u8, network.network().octets().to_vec()),
|
IpNet::V4(network) => (AF_INET as u8, network.network().octets().to_vec()),
|
||||||
IpNetwork::V6(network) => (AF_INET6 as u8, network.network().octets().to_vec()),
|
IpNet::V6(network) => (AF_INET6 as u8, network.network().octets().to_vec()),
|
||||||
};
|
};
|
||||||
let message = RouteMessage {
|
let message = RouteMessage {
|
||||||
header: RouteHeader {
|
header: RouteHeader {
|
||||||
|
@ -84,7 +84,7 @@ pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result<bool, io:
|
||||||
protocol: RTPROT_BOOT,
|
protocol: RTPROT_BOOT,
|
||||||
scope: RT_SCOPE_LINK,
|
scope: RT_SCOPE_LINK,
|
||||||
kind: RTN_UNICAST,
|
kind: RTN_UNICAST,
|
||||||
destination_prefix_length: cidr.prefix(),
|
destination_prefix_length: cidr.prefix_len(),
|
||||||
address_family,
|
address_family,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
interface_config::{InterfaceConfig, InterfaceInfo, ServerInfo},
|
interface_config::{InterfaceConfig, InterfaceInfo, ServerInfo},
|
||||||
AddCidrOpts, AddDeleteAssociationOpts, AddPeerOpts, Association, Cidr, CidrContents, CidrTree,
|
AddCidrOpts, AddDeleteAssociationOpts, AddPeerOpts, Association, Cidr, CidrContents, CidrTree,
|
||||||
DeleteCidrOpts, Endpoint, Error, Hostname, ListenPortOpts, OverrideEndpointOpts, Peer,
|
DeleteCidrOpts, Endpoint, Error, Hostname, IpNetExt, ListenPortOpts, OverrideEndpointOpts,
|
||||||
PeerContents, RenamePeerOpts, PERSISTENT_KEEPALIVE_INTERVAL_SECS,
|
Peer, PeerContents, RenamePeerOpts, PERSISTENT_KEEPALIVE_INTERVAL_SECS,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use colored::*;
|
use colored::*;
|
||||||
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
|
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
|
||||||
use ipnetwork::IpNetwork;
|
use ipnet::IpNet;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use publicip::Preference;
|
use publicip::Preference;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -267,7 +267,7 @@ pub fn add_peer(
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut available_ip = None;
|
let mut available_ip = None;
|
||||||
let candidate_ips = cidr.iter().filter(|ip| cidr.is_assignable(*ip));
|
let candidate_ips = cidr.hosts().filter(|ip| cidr.is_assignable(ip));
|
||||||
for ip in candidate_ips {
|
for ip in candidate_ips {
|
||||||
if !peers.iter().any(|peer| peer.ip == ip) {
|
if !peers.iter().any(|peer| peer.ip == ip) {
|
||||||
available_ip = Some(ip);
|
available_ip = Some(ip);
|
||||||
|
@ -439,7 +439,7 @@ pub fn write_peer_invitation(
|
||||||
interface: InterfaceInfo {
|
interface: InterfaceInfo {
|
||||||
network_name: network_name.to_string(),
|
network_name: network_name.to_string(),
|
||||||
private_key: keypair.private.to_base64(),
|
private_key: keypair.private.to_base64(),
|
||||||
address: IpNetwork::new(peer.ip, root_cidr.prefix())?,
|
address: IpNet::new(peer.ip, root_cidr.prefix_len())?,
|
||||||
listen_port: None,
|
listen_port: None,
|
||||||
},
|
},
|
||||||
server: ServerInfo {
|
server: ServerInfo {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use ipnetwork::IpNetwork;
|
use ipnet::IpNet;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -195,12 +195,12 @@ impl Deref for Association {
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord)]
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Eq, Ord)]
|
||||||
pub struct CidrContents {
|
pub struct CidrContents {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub cidr: IpNetwork,
|
pub cidr: IpNet,
|
||||||
pub parent: Option<i64>,
|
pub parent: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for CidrContents {
|
impl Deref for CidrContents {
|
||||||
type Target = IpNetwork;
|
type Target = IpNet;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.cidr
|
&self.cidr
|
||||||
|
@ -247,7 +247,7 @@ impl<'a> CidrTree<'a> {
|
||||||
pub fn new(cidrs: &'a [Cidr]) -> Self {
|
pub fn new(cidrs: &'a [Cidr]) -> Self {
|
||||||
let root = cidrs
|
let root = cidrs
|
||||||
.iter()
|
.iter()
|
||||||
.min_by_key(|c| c.cidr.prefix())
|
.min_by_key(|c| c.cidr.prefix_len())
|
||||||
.expect("failed to find root CIDR");
|
.expect("failed to find root CIDR");
|
||||||
Self::with_root(cidrs, root)
|
Self::with_root(cidrs, root)
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ pub struct AddCidrOpts {
|
||||||
|
|
||||||
/// The CIDR network (eg. '10.42.5.0/24')
|
/// The CIDR network (eg. '10.42.5.0/24')
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub cidr: Option<IpNetwork>,
|
pub cidr: Option<IpNet>,
|
||||||
|
|
||||||
/// The CIDR parent name
|
/// The CIDR parent name
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
|
@ -431,7 +431,7 @@ pub struct NatOpts {
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
/// Exclude one or more CIDRs from NAT candidate reporting.
|
/// Exclude one or more CIDRs from NAT candidate reporting.
|
||||||
/// ex. --exclude-nat-candidates '0.0.0.0/0' would report no candidates.
|
/// ex. --exclude-nat-candidates '0.0.0.0/0' would report no candidates.
|
||||||
pub exclude_nat_candidates: Vec<IpNetwork>,
|
pub exclude_nat_candidates: Vec<IpNet>,
|
||||||
|
|
||||||
#[clap(long, conflicts_with = "exclude-nat-candidates")]
|
#[clap(long, conflicts_with = "exclude-nat-candidates")]
|
||||||
/// Don't report any candidates to coordinating server.
|
/// Don't report any candidates to coordinating server.
|
||||||
|
@ -454,7 +454,7 @@ impl NatOpts {
|
||||||
|| self
|
|| self
|
||||||
.exclude_nat_candidates
|
.exclude_nat_candidates
|
||||||
.iter()
|
.iter()
|
||||||
.any(|network| network.contains(ip))
|
.any(|network| network.contains(&ip))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{Error, IoErrorContext, NetworkOpts, Peer, PeerDiff};
|
use crate::{Error, IoErrorContext, NetworkOpts, Peer, PeerDiff};
|
||||||
use ipnetwork::IpNetwork;
|
use ipnet::IpNet;
|
||||||
use std::{
|
use std::{
|
||||||
io,
|
io,
|
||||||
net::{IpAddr, SocketAddr},
|
net::{IpAddr, SocketAddr},
|
||||||
|
@ -32,17 +32,17 @@ fn cmd(bin: &str, args: &[&str]) -> Result<std::process::Output, io::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub fn set_addr(interface: &InterfaceName, addr: IpNetwork) -> Result<(), io::Error> {
|
pub fn set_addr(interface: &InterfaceName, addr: IpNet) -> Result<(), io::Error> {
|
||||||
let real_interface = wireguard_control::backends::userspace::resolve_tun(interface)?;
|
let real_interface = wireguard_control::backends::userspace::resolve_tun(interface)?;
|
||||||
|
|
||||||
if addr.is_ipv4() {
|
if matches!(addr, IpNet::V4(_)) {
|
||||||
cmd(
|
cmd(
|
||||||
"ifconfig",
|
"ifconfig",
|
||||||
&[
|
&[
|
||||||
&real_interface,
|
&real_interface,
|
||||||
"inet",
|
"inet",
|
||||||
&addr.to_string(),
|
&addr.to_string(),
|
||||||
&addr.ip().to_string(),
|
&addr.addr().to_string(),
|
||||||
"alias",
|
"alias",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -72,7 +72,7 @@ pub use super::netlink::set_up;
|
||||||
pub fn up(
|
pub fn up(
|
||||||
interface: &InterfaceName,
|
interface: &InterfaceName,
|
||||||
private_key: &str,
|
private_key: &str,
|
||||||
address: IpNetwork,
|
address: IpNet,
|
||||||
listen_port: Option<u16>,
|
listen_port: Option<u16>,
|
||||||
peer: Option<(&str, IpAddr, SocketAddr)>,
|
peer: Option<(&str, IpAddr, SocketAddr)>,
|
||||||
network: NetworkOpts,
|
network: NetworkOpts,
|
||||||
|
@ -102,9 +102,11 @@ pub fn up(
|
||||||
set_addr(interface, address)?;
|
set_addr(interface, address)?;
|
||||||
set_up(
|
set_up(
|
||||||
interface,
|
interface,
|
||||||
network
|
network.mtu.unwrap_or(if matches!(address, IpNet::V4(_)) {
|
||||||
.mtu
|
1420
|
||||||
.unwrap_or_else(|| if address.is_ipv4() { 1420 } else { 1400 }),
|
} else {
|
||||||
|
1400
|
||||||
|
}),
|
||||||
)?;
|
)?;
|
||||||
if !network.no_routing {
|
if !network.no_routing {
|
||||||
add_route(interface, address)?;
|
add_route(interface, address)?;
|
||||||
|
@ -139,14 +141,18 @@ pub fn down(interface: &InterfaceName, backend: Backend) -> Result<(), Error> {
|
||||||
/// Returns an error if the process doesn't exit successfully, otherwise returns
|
/// Returns an error if the process doesn't exit successfully, otherwise returns
|
||||||
/// true if the route was changed, false if the route already exists.
|
/// true if the route was changed, false if the route already exists.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub fn add_route(interface: &InterfaceName, cidr: IpNetwork) -> Result<bool, io::Error> {
|
pub fn add_route(interface: &InterfaceName, cidr: IpNet) -> Result<bool, io::Error> {
|
||||||
let real_interface = wireguard_control::backends::userspace::resolve_tun(interface)?;
|
let real_interface = wireguard_control::backends::userspace::resolve_tun(interface)?;
|
||||||
let output = cmd(
|
let output = cmd(
|
||||||
"route",
|
"route",
|
||||||
&[
|
&[
|
||||||
"-n",
|
"-n",
|
||||||
"add",
|
"add",
|
||||||
if cidr.is_ipv4() { "-inet" } else { "-inet6" },
|
if matches!(cidr, IpNet::V4(_)) {
|
||||||
|
"-inet"
|
||||||
|
} else {
|
||||||
|
"-inet6"
|
||||||
|
},
|
||||||
&cidr.to_string(),
|
&cidr.to_string(),
|
||||||
"-interface",
|
"-interface",
|
||||||
&real_interface,
|
&real_interface,
|
||||||
|
|
Loading…
Reference in New Issue