progress [CI SKIP]
This commit is contained in:
parent
a8be702e88
commit
a6af494cb9
@ -1,4 +1,6 @@
|
||||
use crate::model::{Base64Backed, ECCKey, Interface, Peer, PeerBuilder, SharedKey, WireguardController};
|
||||
use crate::model::{
|
||||
Base64Backed, ECCKey, Interface, Peer, PeerBuilder, SharedKey, WireguardController,
|
||||
};
|
||||
use std::io::{BufRead, BufReader, Error, ErrorKind, Result, Write};
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::os::unix::net::UnixStream;
|
||||
@ -46,6 +48,10 @@ impl WireguardController for Userspace {
|
||||
Ok(())
|
||||
};
|
||||
match key.as_ref() {
|
||||
"" => {
|
||||
//Empty line means end of data
|
||||
build_peer(&mut peer, builder); //TODO: handle possible actual error case
|
||||
}
|
||||
"public_key" => {
|
||||
add_key(&mut peer, parse_err(ECCKey::from_base64(value))?)?;
|
||||
}
|
||||
@ -64,9 +70,15 @@ impl WireguardController for Userspace {
|
||||
"last_handshake_time_nsec" => {
|
||||
builder.add_last_handshake(Duration::from_nanos(value_as_num()?.into()));
|
||||
}
|
||||
"persistent_keepalive" => {
|
||||
"persistent_keepalive_interval" => {
|
||||
builder.persistent_keepalive(Some(Duration::from_secs(value_as_num()?.into())));
|
||||
}
|
||||
"rx_bytes" => {
|
||||
builder.add_traffic((parse_err(value.parse::<u64>())?, 0));
|
||||
}
|
||||
"tx_bytes" => {
|
||||
builder.add_traffic((0, (parse_err(value.parse::<u64>())?)));
|
||||
}
|
||||
"allowed_ip" => {
|
||||
let mut parts = value.split("/").into_iter();
|
||||
let net = match (
|
||||
@ -89,7 +101,11 @@ impl WireguardController for Userspace {
|
||||
format!("Returned error code: {}", code),
|
||||
))?,
|
||||
},
|
||||
_ => Err(Error::new(ErrorKind::InvalidData, "Unknown key"))?,
|
||||
"listen_port" | "fwmark" | "private_key" => (), //Ignore for now
|
||||
_ => Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
["Unknown key: \"", &key, "\""].join(""),
|
||||
))?,
|
||||
}
|
||||
Ok(peer)
|
||||
}
|
||||
@ -102,7 +118,7 @@ impl WireguardController for Userspace {
|
||||
Err(err) => {
|
||||
eprintln!("{:?}", err);
|
||||
None
|
||||
}, //TODO: propagate
|
||||
} //TODO: propagate
|
||||
_ => Some(None),
|
||||
}
|
||||
})
|
||||
|
@ -8,28 +8,42 @@ mod controller;
|
||||
mod model;
|
||||
mod opts;
|
||||
|
||||
use controller::{Userspace};
|
||||
use controller::Userspace;
|
||||
use model::WireguardController;
|
||||
use opts::Opts;
|
||||
use std::io;
|
||||
use structopt::StructOpt;
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration,Instant};
|
||||
use std::time::{Duration, Instant};
|
||||
use structopt::StructOpt;
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let opts = Opts::from_args();
|
||||
let mut controller: Box<WireguardController> = Box::new(Userspace::new(opts.socket.clone()));
|
||||
let interval = Duration::from_millis(opts.poll);
|
||||
println!("Polling {} every {:?}", opts.socket.to_str().unwrap(), interval);
|
||||
let timeout = Duration::from_secs(opts.timeout);
|
||||
println!(
|
||||
"Polling {} every {:?}",
|
||||
opts.socket.to_str().unwrap(),
|
||||
interval
|
||||
);
|
||||
loop {
|
||||
let now = Instant::now();
|
||||
let peers = controller.peers()?;
|
||||
println!("Connected peers:");
|
||||
for peer in peers {
|
||||
dbg!(peer?);
|
||||
let peer = peer?;
|
||||
dbg!(peer.last_handshake);
|
||||
if peer.last_handshake.map(|h| h < timeout).unwrap_or(false) {
|
||||
println!("{:?}", peer.key);
|
||||
}
|
||||
}
|
||||
let pause = interval - now.elapsed();
|
||||
dbg!(pause);
|
||||
sleep(if pause > interval/2 { pause } else {interval});
|
||||
sleep(if pause > interval / 2 {
|
||||
pause
|
||||
} else {
|
||||
interval
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,19 +1,22 @@
|
||||
use base64::{decode, encode};
|
||||
use std::error::Error;
|
||||
use std::hash::Hash;
|
||||
use std::io;
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
const KEY_SIZE: usize = 48; //TODO: use VEC instead of array
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub enum ECCKey {
|
||||
PublicKey([u8; 32]),
|
||||
PrivateKey([u8; 32]),
|
||||
PublicKey(Vec<u8>),
|
||||
PrivateKey(Vec<u8>),
|
||||
}
|
||||
|
||||
pub trait Base64Backed {
|
||||
fn from_bytes(bytes: [u8; 32]) -> Self;
|
||||
fn bytes(&self) -> &[u8; 32];
|
||||
fn from_bytes(bytes: Vec<u8>) -> Self;
|
||||
fn bytes(&self) -> &Vec<u8>;
|
||||
fn from_base64<I: AsRef<str>>(key: I) -> io::Result<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
@ -29,12 +32,17 @@ pub trait Base64Backed {
|
||||
}; /*.map_err(|err| {
|
||||
|
||||
})?;*/
|
||||
let mut bytes = [0; 32];
|
||||
if key.len() != 32 {
|
||||
return Err(io::Error::new(io::ErrorKind::Other, "Mismatched key size"));
|
||||
if key.len() != KEY_SIZE {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!(
|
||||
"Mismatched key size. Expected: {}, Got {}",
|
||||
KEY_SIZE,
|
||||
key.len()
|
||||
),
|
||||
));
|
||||
}
|
||||
bytes.copy_from_slice(&key);
|
||||
Ok(Self::from_bytes(bytes))
|
||||
Ok(Self::from_bytes(key))
|
||||
}
|
||||
|
||||
fn as_base64(&self) -> io::Result<String> {
|
||||
@ -43,14 +51,14 @@ pub trait Base64Backed {
|
||||
}
|
||||
|
||||
impl Base64Backed for ECCKey {
|
||||
fn bytes(&self) -> &[u8; 32] {
|
||||
fn bytes(&self) -> &Vec<u8> {
|
||||
match self {
|
||||
ECCKey::PublicKey(bytes) => &bytes,
|
||||
ECCKey::PrivateKey(bytes) => &bytes,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_bytes(bytes: [u8; 32]) -> ECCKey {
|
||||
fn from_bytes(bytes: Vec<u8>) -> ECCKey {
|
||||
ECCKey::PublicKey(bytes)
|
||||
}
|
||||
}
|
||||
@ -62,40 +70,42 @@ impl ECCKey {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub struct SharedKey([u8; 32]);
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct SharedKey(Vec<u8>);
|
||||
|
||||
impl Base64Backed for SharedKey {
|
||||
fn bytes(&self) -> &[u8; 32] {
|
||||
fn bytes(&self) -> &Vec<u8> {
|
||||
&self.0
|
||||
}
|
||||
fn from_bytes(bytes: [u8; 32]) -> SharedKey {
|
||||
fn from_bytes(bytes: Vec<u8>) -> SharedKey {
|
||||
SharedKey(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Builder, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct Interface {
|
||||
key: ECCKey,
|
||||
port: usize,
|
||||
fwmark: Option<String>
|
||||
pub key: ECCKey,
|
||||
pub port: usize,
|
||||
pub fwmark: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Builder, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct Peer {
|
||||
key: ECCKey,
|
||||
pub key: ECCKey,
|
||||
#[builder(default = "None")]
|
||||
shared_key: Option<SharedKey>,
|
||||
pub shared_key: Option<SharedKey>,
|
||||
#[builder(default = "None")]
|
||||
endpoint: Option<SocketAddr>,
|
||||
allowed_ips: Vec<(IpAddr, u8)>,
|
||||
last_handshake: Option<Duration>,
|
||||
pub endpoint: Option<SocketAddr>,
|
||||
#[builder(default = "Vec::new()")]
|
||||
pub allowed_ips: Vec<(IpAddr, u8)>,
|
||||
#[builder(default = "None")]
|
||||
persistent_keepalive: Option<Duration>,
|
||||
pub last_handshake: Option<Duration>,
|
||||
#[builder(default = "None")]
|
||||
pub persistent_keepalive: Option<Duration>,
|
||||
#[builder(default = "(0u64,0u64)")]
|
||||
traffic: (u64, u64),
|
||||
pub traffic: (u64, u64),
|
||||
#[builder(default = "Instant::now()")]
|
||||
parsed: Instant,
|
||||
pub parsed: Instant,
|
||||
}
|
||||
|
||||
impl PeerBuilder {
|
||||
@ -128,6 +138,15 @@ impl PeerBuilder {
|
||||
.map(|shake| shake.map(|shake| shake + d));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_traffic(&mut self, txrx: (u64, u64)) {
|
||||
if let Some(ref mut traffic) = &mut self.traffic {
|
||||
traffic.0 += txrx.0;
|
||||
traffic.1 += txrx.1;
|
||||
} else {
|
||||
self.traffic = Some(txrx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait WireguardController {
|
||||
|
Loading…
x
Reference in New Issue
Block a user