aboutsummaryrefslogtreecommitdiffstats
path: root/src/interface
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-02-14 14:23:57 +0000
committerJake McGinty <me@jake.su>2018-02-14 14:39:30 +0000
commita987887682bd6658a63d93ea6bc30fe3aff038a8 (patch)
tree7a8e183882bdd94da0e2680db930a8227ed8b52e /src/interface
parentsquish superfluous map_err (diff)
downloadwireguard-rs-a987887682bd6658a63d93ea6bc30fe3aff038a8.tar.xz
wireguard-rs-a987887682bd6658a63d93ea6bc30fe3aff038a8.zip
deshittify the config parser
Diffstat (limited to 'src/interface')
-rw-r--r--src/interface/config.rs72
-rw-r--r--src/interface/mod.rs6
2 files changed, 30 insertions, 48 deletions
diff --git a/src/interface/config.rs b/src/interface/config.rs
index 9df7b7b..73f445e 100644
--- a/src/interface/config.rs
+++ b/src/interface/config.rs
@@ -7,6 +7,7 @@ use bytes::BytesMut;
use failure::Error;
use std;
use std::fs::{create_dir, remove_file};
+use std::mem;
use std::iter::Iterator;
use std::path::{Path, PathBuf};
use std::io;
@@ -37,58 +38,39 @@ pub enum UpdateEvent {
}
impl UpdateEvent {
- fn from(items: Vec<(String, String)>) -> Vec<UpdateEvent> {
+ fn from(items: Vec<(String, String)>) -> Result<Vec<UpdateEvent>, Error> {
let mut events = vec![];
- let mut public_key: Option<[u8; 32]> = None;
- let mut preshared_key: Option<[u8; 32]> = None;
- let mut allowed_ips: Vec<(IpAddr, u32)> = vec![];
- let mut keep_alive_interval: Option<u16> = None;
- let mut endpoint: Option<SocketAddr> = None;
+ let mut pending_peer = false;
+ let mut info = PeerInfo::default();
for (key, value) in items {
match key.as_ref() {
- "private_key" => {
- let key = <[u8; 32]>::from_hex(&value).unwrap();
- events.push(UpdateEvent::PrivateKey(key));
- },
- "listen_port" => { events.push(UpdateEvent::ListenPort(value.parse().unwrap())); },
+ "private_key" => { events.push(UpdateEvent::PrivateKey(<[u8; 32]>::from_hex(&value)?)); },
+ "listen_port" => { events.push(UpdateEvent::ListenPort(value.parse()?)); },
"public_key" => {
- if let Some(ref pubkey) = public_key {
- events.push(UpdateEvent::UpdatePeer(PeerInfo {
- pub_key: pubkey.clone(),
- psk: preshared_key.clone(),
- endpoint: endpoint.clone(),
- allowed_ips: allowed_ips.clone(),
- keep_alive_interval: keep_alive_interval.clone(),
- }));
+ if pending_peer {
+ events.push(UpdateEvent::UpdatePeer(mem::replace(&mut info, PeerInfo::default())));
}
- let key = <[u8; 32]>::from_hex(&value).unwrap();
- public_key = Some(key);
+ info.pub_key = <[u8; 32]>::from_hex(&value)?;
+ pending_peer = true;
},
- "preshared_key" => { preshared_key = Some(<[u8; 32]>::from_hex(&value).unwrap()); },
+ "preshared_key" => { info.psk = Some(<[u8; 32]>::from_hex(&value)?); },
+ "persistent_keepalive_interval" => { info.keep_alive_interval = Some(value.parse()?); },
+ "endpoint" => { info.endpoint = Some(value.parse()?); },
"allowed_ip" => {
- let (ip, cidr) = value.split_at(value.find('/').unwrap());
- allowed_ips.push((ip.parse().unwrap(), (&cidr[1..]).parse().unwrap()))
- },
- "persistent_keepalive_interval" => {
- keep_alive_interval = Some(value.parse().unwrap());
+ let (ip, cidr) = value.split_at(value.find('/').ok_or_else(|| format_err!("ip/cidr format error"))?);
+ info.allowed_ips.push((ip.parse()?, (&cidr[1..]).parse()?))
},
- "endpoint" => { endpoint = Some(value.parse().unwrap()); },
- _ => {}
+ _ => { warn!("unrecognized configuration pair: {}={}", key, value)}
}
}
- if let Some(ref pubkey) = public_key {
- events.push(UpdateEvent::UpdatePeer(PeerInfo {
- pub_key: pubkey.clone(),
- psk: preshared_key.clone(),
- endpoint: endpoint.clone(),
- allowed_ips: allowed_ips.clone(),
- keep_alive_interval: keep_alive_interval.clone(),
- }));
+ // "flush" the final peer if there is one
+ if pending_peer {
+ events.push(UpdateEvent::UpdatePeer(info));
}
- debug!("events {:?}", events);
- events
+ trace!("events {:?}", events);
+ Ok(events)
}
}
@@ -96,7 +78,7 @@ pub struct ConfigurationCodec;
impl Decoder for ConfigurationCodec {
type Item = Command;
- type Error = io::Error;
+ type Error = Error;
fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
// Determine we have a full command ready for parsing.
@@ -116,10 +98,10 @@ impl Decoder for ConfigurationCodec {
buf.split_to(blob.len()+1);
let (ref cmd, ref version) = items.remove(0);
- let command = if cmd == "get" {
- Command::Get(version.parse().unwrap())
- } else {
- Command::Set(version.parse().unwrap(), UpdateEvent::from(items))
+ let command = match cmd.as_str() {
+ "get" => Command::Get(version.parse()?),
+ "set" => Command::Set(version.parse()?, UpdateEvent::from(items)?),
+ _ => bail!("invalid command")
};
Ok(Some(command))
@@ -128,7 +110,7 @@ impl Decoder for ConfigurationCodec {
impl Encoder for ConfigurationCodec {
type Item = String;
- type Error = io::Error;
+ type Error = Error;
fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> Result<(), Self::Error> {
buf.extend(msg.as_bytes());
diff --git a/src/interface/mod.rs b/src/interface/mod.rs
index 38c306c..4a091c1 100644
--- a/src/interface/mod.rs
+++ b/src/interface/mod.rs
@@ -192,14 +192,14 @@ impl Interface {
match event {
UpdateEvent::PrivateKey(private_key) => {
let pub_key = x25519::generate_public(&private_key);
- info!("our pubkey: {}", base64::encode(pub_key.as_bytes()));
+ info!("set pubkey: {}", base64::encode(pub_key.as_bytes()));
state.interface_info.private_key = Some(private_key);
state.interface_info.pub_key = Some(*pub_key.as_bytes());
- debug!("set new private key");
+ debug!("set new private key.");
},
UpdateEvent::ListenPort(port) => {
state.interface_info.listen_port = Some(port);
- debug!("set new listen port");
+ info!("set listen port: {}", port);
},
UpdateEvent::UpdatePeer(info) => {
info!("added new peer: {}", info);