161 lines
4.3 KiB
Rust
161 lines
4.3 KiB
Rust
use crate::Peer;
|
|
use std::net::SocketAddr;
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
use std::thread;
|
|
use std::time::SystemTime;
|
|
|
|
pub trait EventListener {
|
|
fn added<'a>(&self, peer: &'a Peer) {
|
|
self.connected(peer);
|
|
}
|
|
|
|
fn connected<'a>(&self, peer: &'a Peer);
|
|
|
|
fn disconnected<'a>(&self, peer: &'a Peer);
|
|
|
|
fn removed<'a>(&self, peer: &'a Peer) {
|
|
self.disconnected(peer)
|
|
}
|
|
|
|
fn roaming<'a>(&self, peer: &'a Peer, previous_addr: SocketAddr);
|
|
}
|
|
|
|
impl EventListener for Vec<Box<EventListener>> {
|
|
fn added<'a>(&self, peer: &'a Peer) {
|
|
if cfg!(feature = "addrem") || cfg!(test) {
|
|
self.iter().for_each(|l| l.added(&peer));
|
|
}
|
|
}
|
|
|
|
fn connected<'a>(&self, peer: &'a Peer) {
|
|
self.iter().for_each(|l| l.connected(&peer));
|
|
}
|
|
|
|
fn disconnected<'a>(&self, peer: &'a Peer) {
|
|
self.iter().for_each(|l| l.disconnected(&peer));
|
|
}
|
|
|
|
fn removed<'a>(&self, peer: &'a Peer) {
|
|
if cfg!(feature = "addrem") || cfg!(test) {
|
|
self.iter().for_each(|l| l.removed(&peer));
|
|
}
|
|
}
|
|
|
|
fn roaming<'a>(&self, peer: &'a Peer, previous_addr: SocketAddr) {
|
|
self.iter().for_each(|l| l.roaming(&peer, previous_addr));
|
|
}
|
|
}
|
|
|
|
pub struct LogListener;
|
|
|
|
impl EventListener for LogListener {
|
|
fn connected<'a>(&self, peer: &'a Peer) {
|
|
println!("{} connected!", peer.key);
|
|
}
|
|
|
|
fn disconnected<'a>(&self, peer: &'a Peer) {
|
|
println!("{} disconnected!", peer.key);
|
|
}
|
|
|
|
fn added<'a>(&self, peer: &'a Peer) {
|
|
println!("{} added!", peer.key);
|
|
}
|
|
|
|
fn removed<'a>(&self, peer: &'a Peer) {
|
|
println!("{} removed!", peer.key);
|
|
}
|
|
|
|
fn roaming<'a>(&self, peer: &'a Peer, previous_addr: SocketAddr) {
|
|
println!(
|
|
"{} roamed {} -> {}!",
|
|
peer.key,
|
|
previous_addr,
|
|
peer.endpoint.unwrap()
|
|
);
|
|
}
|
|
}
|
|
|
|
pub struct ScriptListener {
|
|
pub script: PathBuf,
|
|
}
|
|
|
|
impl ScriptListener {
|
|
pub fn new(script: PathBuf) -> ScriptListener {
|
|
ScriptListener { script }
|
|
}
|
|
|
|
fn peer_props<'a>(&self, peer: &'a Peer) -> String {
|
|
format!(
|
|
"{id} {allowed_ips} {endpoint} {last_handshake} {persistent_keepalive} {traffic}",
|
|
id = peer.key,
|
|
allowed_ips = peer
|
|
.allowed_ips
|
|
.iter()
|
|
.map(|(addr, mask)| [addr.to_string(), mask.to_string()].join("/"))
|
|
.collect::<Vec<String>>()
|
|
.join(","),
|
|
endpoint = peer
|
|
.endpoint
|
|
.map(|e| e.to_string())
|
|
.unwrap_or("0".to_owned()),
|
|
last_handshake = peer
|
|
.last_handshake
|
|
.map(|s| s.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as i64)
|
|
.unwrap_or(-1),
|
|
persistent_keepalive = peer
|
|
.persistent_keepalive
|
|
.map(|k| k.as_secs() as i64)
|
|
.unwrap_or(-1),
|
|
traffic = {
|
|
let (rx, tx) = peer.traffic;
|
|
[rx.to_string(), tx.to_string()].join(",")
|
|
}
|
|
)
|
|
}
|
|
|
|
fn mkcmd<'a>(&self, args: Vec<&'a str>) -> Command {
|
|
let mut cmd = Command::new("/bin/sh");
|
|
cmd.arg("-c");
|
|
cmd.arg(format!(
|
|
"{} {}",
|
|
(&self.script).to_str().unwrap(),
|
|
args.join(" ")
|
|
));
|
|
cmd
|
|
}
|
|
|
|
fn call_sub<'a>(&self, args: Vec<&'a str>) {
|
|
let mut cmd = self.mkcmd(args);
|
|
thread::spawn(move || {
|
|
cmd.spawn().expect("Failed to call Script hooḱ!");
|
|
});
|
|
}
|
|
}
|
|
|
|
impl EventListener for ScriptListener {
|
|
fn connected<'a>(&self, peer: &'a Peer) {
|
|
self.call_sub(vec!["connected", &self.peer_props(peer)]);
|
|
}
|
|
|
|
fn disconnected<'a>(&self, peer: &'a Peer) {
|
|
self.call_sub(vec!["disconnected", &self.peer_props(peer)]);
|
|
}
|
|
|
|
fn added<'a>(&self, peer: &'a Peer) {
|
|
self.call_sub(vec!["added", &self.peer_props(peer)]);
|
|
}
|
|
|
|
fn removed<'a>(&self, peer: &'a Peer) {
|
|
self.call_sub(vec!["removed", &self.peer_props(peer)]);
|
|
}
|
|
|
|
fn roaming<'a>(&self, peer: &'a Peer, previous_addr: SocketAddr) {
|
|
self.call_sub(vec![
|
|
"roaming",
|
|
&self.peer_props(peer),
|
|
&previous_addr.to_string(),
|
|
]);
|
|
}
|
|
}
|