Turn ChangeString into a PeerChange enum (#263)
* Turn ChangeString into a PeerChange enum, don't print NAT traversal reattempt as a modification * Remove the ChangeString type * Fix a stupid copy-paste errorpull/175/head
parent
bd4aabe787
commit
0057a703ff
|
@ -3,7 +3,9 @@ use colored::*;
|
||||||
use indoc::eprintdoc;
|
use indoc::eprintdoc;
|
||||||
use log::{Level, LevelFilter};
|
use log::{Level, LevelFilter};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use shared::{interface_config::ServerInfo, Interface, PeerDiff, INNERNET_PUBKEY_HEADER};
|
use shared::{
|
||||||
|
interface_config::ServerInfo, Interface, PeerChange, PeerDiff, INNERNET_PUBKEY_HEADER,
|
||||||
|
};
|
||||||
use std::{ffi::OsStr, io, path::Path, time::Duration};
|
use std::{ffi::OsStr, io, path::Path, time::Duration};
|
||||||
use ureq::{Agent, AgentBuilder};
|
use ureq::{Agent, AgentBuilder};
|
||||||
|
|
||||||
|
@ -137,13 +139,30 @@ pub fn permissions_helptext(config_dir: &Path, data_dir: &Path, e: &io::Error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
enum ChangeAction {
|
||||||
|
Added,
|
||||||
|
Modified,
|
||||||
|
Removed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChangeAction {
|
||||||
|
fn colored_output(&self) -> ColoredString {
|
||||||
|
match self {
|
||||||
|
Self::Added => "added".green(),
|
||||||
|
Self::Modified => "modified".yellow(),
|
||||||
|
Self::Removed => "removed".red(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print_peer_diff(store: &DataStore, diff: &PeerDiff) {
|
pub fn print_peer_diff(store: &DataStore, diff: &PeerDiff) {
|
||||||
let public_key = diff.public_key().to_base64();
|
let public_key = diff.public_key().to_base64();
|
||||||
|
|
||||||
let text = match (diff.old, diff.new) {
|
let change_action = match (diff.old, diff.new) {
|
||||||
(None, Some(_)) => "added".green(),
|
(None, Some(_)) => ChangeAction::Added,
|
||||||
(Some(_), Some(_)) => "modified".yellow(),
|
(Some(_), Some(_)) => ChangeAction::Modified,
|
||||||
(Some(_), None) => "removed".red(),
|
(Some(_), None) => ChangeAction::Removed,
|
||||||
_ => unreachable!("PeerDiff can't be None -> None"),
|
_ => unreachable!("PeerDiff can't be None -> None"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,16 +177,31 @@ pub fn print_peer_diff(store: &DataStore, diff: &PeerDiff) {
|
||||||
};
|
};
|
||||||
let peer_name = peer_hostname.as_deref().unwrap_or("[unknown]");
|
let peer_name = peer_hostname.as_deref().unwrap_or("[unknown]");
|
||||||
|
|
||||||
|
if change_action == ChangeAction::Modified
|
||||||
|
&& diff
|
||||||
|
.changes()
|
||||||
|
.iter()
|
||||||
|
.all(|c| *c == PeerChange::NatTraverseReattempt)
|
||||||
|
{
|
||||||
|
// If this peer was "modified" but the only change is a NAT Traversal Reattempt,
|
||||||
|
// don't bother printing this peer.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
" peer {} ({}...) was {}.",
|
" peer {} ({}...) was {}.",
|
||||||
peer_name.yellow(),
|
peer_name.yellow(),
|
||||||
&public_key[..10].dimmed(),
|
&public_key[..10].dimmed(),
|
||||||
text
|
change_action.colored_output(),
|
||||||
);
|
);
|
||||||
|
|
||||||
for change in diff.changes() {
|
for change in diff.changes() {
|
||||||
|
if let PeerChange::Endpoint { .. } = change {
|
||||||
|
log::info!(" {}", change);
|
||||||
|
} else {
|
||||||
log::debug!(" {}", change);
|
log::debug!(" {}", change);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_installed(config_dir: &Path) -> Result<Vec<Interface>, std::io::Error> {
|
pub fn all_installed(config_dir: &Path) -> Result<Vec<Interface>, std::io::Error> {
|
||||||
|
|
|
@ -519,35 +519,55 @@ impl Display for Peer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ChangeString {
|
pub enum PeerChange {
|
||||||
name: &'static str,
|
AllowedIPs {
|
||||||
old: Option<String>,
|
old: Vec<AllowedIp>,
|
||||||
new: Option<String>,
|
new: Vec<AllowedIp>,
|
||||||
|
},
|
||||||
|
PersistentKeepalive {
|
||||||
|
old: Option<u16>,
|
||||||
|
new: Option<u16>,
|
||||||
|
},
|
||||||
|
Endpoint {
|
||||||
|
old: Option<SocketAddr>,
|
||||||
|
new: Option<SocketAddr>,
|
||||||
|
},
|
||||||
|
NatTraverseReattempt,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ChangeString {
|
impl Display for PeerChange {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
match self {
|
||||||
|
Self::AllowedIPs { old, new } => write!(f, "Allowed IPs: {:?} => {:?}", old, new),
|
||||||
|
Self::PersistentKeepalive { old, new } => write!(
|
||||||
f,
|
f,
|
||||||
"{}: {} => {}",
|
"Persistent Keepalive: {} => {}",
|
||||||
self.name,
|
old.display_string(),
|
||||||
self.old.as_deref().unwrap_or("[none]"),
|
new.display_string()
|
||||||
self.new.as_deref().unwrap_or("[none]")
|
),
|
||||||
)
|
Self::Endpoint { old, new } => write!(
|
||||||
|
f,
|
||||||
|
"Endpoint: {} => {}",
|
||||||
|
old.display_string(),
|
||||||
|
new.display_string()
|
||||||
|
),
|
||||||
|
Self::NatTraverseReattempt => write!(f, "NAT Traversal Reattempt"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChangeString {
|
trait OptionExt {
|
||||||
pub fn new<T, U>(name: &'static str, old: Option<T>, new: Option<U>) -> Self
|
fn display_string(&self) -> String;
|
||||||
where
|
}
|
||||||
T: fmt::Debug,
|
|
||||||
U: fmt::Debug,
|
impl<T: std::fmt::Debug> OptionExt for Option<T> {
|
||||||
{
|
fn display_string(&self) -> String {
|
||||||
Self {
|
match self {
|
||||||
name,
|
Some(x) => {
|
||||||
old: old.map(|t| format!("{t:?}")),
|
format!("{:?}", x)
|
||||||
new: new.map(|t| format!("{t:?}")),
|
},
|
||||||
|
None => "[none]".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -559,7 +579,7 @@ pub struct PeerDiff<'a> {
|
||||||
pub old: Option<&'a PeerConfig>,
|
pub old: Option<&'a PeerConfig>,
|
||||||
pub new: Option<&'a Peer>,
|
pub new: Option<&'a Peer>,
|
||||||
builder: PeerConfigBuilder,
|
builder: PeerConfigBuilder,
|
||||||
changes: Vec<ChangeString>,
|
changes: Vec<PeerChange>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PeerDiff<'a> {
|
impl<'a> PeerDiff<'a> {
|
||||||
|
@ -588,14 +608,14 @@ impl<'a> PeerDiff<'a> {
|
||||||
self.builder.public_key()
|
self.builder.public_key()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn changes(&self) -> &[ChangeString] {
|
pub fn changes(&self) -> &[PeerChange] {
|
||||||
&self.changes
|
&self.changes
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peer_config_builder(
|
fn peer_config_builder(
|
||||||
old_info: Option<&PeerInfo>,
|
old_info: Option<&PeerInfo>,
|
||||||
new: Option<&Peer>,
|
new: Option<&Peer>,
|
||||||
) -> Option<(PeerConfigBuilder, Vec<ChangeString>)> {
|
) -> Option<(PeerConfigBuilder, Vec<PeerChange>)> {
|
||||||
let old = old_info.map(|p| &p.config);
|
let old = old_info.map(|p| &p.config);
|
||||||
let public_key = match (old, new) {
|
let public_key = match (old, new) {
|
||||||
(Some(old), _) => old.public_key.clone(),
|
(Some(old), _) => old.public_key.clone(),
|
||||||
|
@ -622,11 +642,10 @@ impl<'a> PeerDiff<'a> {
|
||||||
builder = builder
|
builder = builder
|
||||||
.replace_allowed_ips()
|
.replace_allowed_ips()
|
||||||
.add_allowed_ips(new_allowed_ips);
|
.add_allowed_ips(new_allowed_ips);
|
||||||
changes.push(ChangeString::new(
|
changes.push(PeerChange::AllowedIPs {
|
||||||
"AllowedIPs",
|
old: old.map(|o| o.allowed_ips.clone()).unwrap_or_else(Vec::new),
|
||||||
old.map(|o| &o.allowed_ips[..]),
|
new: new_allowed_ips.to_vec(),
|
||||||
Some(&new_allowed_ips[0]),
|
});
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if old.is_none()
|
if old.is_none()
|
||||||
|
@ -636,11 +655,10 @@ impl<'a> PeerDiff<'a> {
|
||||||
Some(interval) => builder.set_persistent_keepalive_interval(interval),
|
Some(interval) => builder.set_persistent_keepalive_interval(interval),
|
||||||
None => builder.unset_persistent_keepalive(),
|
None => builder.unset_persistent_keepalive(),
|
||||||
};
|
};
|
||||||
changes.push(ChangeString::new(
|
changes.push(PeerChange::PersistentKeepalive {
|
||||||
"PersistentKeepalive",
|
old: old.and_then(|p| p.persistent_keepalive_interval),
|
||||||
old.and_then(|p| p.persistent_keepalive_interval),
|
new: new.persistent_keepalive_interval,
|
||||||
new.persistent_keepalive_interval,
|
});
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We won't update the endpoint if there's already a stable connection.
|
// We won't update the endpoint if there's already a stable connection.
|
||||||
|
@ -653,20 +671,15 @@ impl<'a> PeerDiff<'a> {
|
||||||
if let Some(addr) = resolved {
|
if let Some(addr) = resolved {
|
||||||
if old.is_none() || matches!(old, Some(old) if old.endpoint != resolved) {
|
if old.is_none() || matches!(old, Some(old) if old.endpoint != resolved) {
|
||||||
builder = builder.set_endpoint(addr);
|
builder = builder.set_endpoint(addr);
|
||||||
changes.push(ChangeString::new(
|
changes.push(PeerChange::Endpoint {
|
||||||
"Endpoint",
|
old: old.and_then(|p| p.endpoint),
|
||||||
old.and_then(|p| p.endpoint),
|
new: Some(addr),
|
||||||
Some(addr),
|
});
|
||||||
));
|
|
||||||
endpoint_changed = true;
|
endpoint_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !endpoint_changed && !new.candidates.is_empty() {
|
if !endpoint_changed && !new.candidates.is_empty() {
|
||||||
changes.push(ChangeString::new(
|
changes.push(PeerChange::NatTraverseReattempt)
|
||||||
"Connection status",
|
|
||||||
"Disconnected".into(),
|
|
||||||
"NAT traverse reattempt".into(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue