Shimun 819eb7d362
Some checks are pending
continuous-integration/drone/push Build is running
integrate old code
2019-03-31 18:04:01 +02:00

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(),
]);
}
}