aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-02-08 16:37:49 +0000
committerJake McGinty <me@jake.su>2018-02-08 16:37:49 +0000
commitf33390ebb9b8248f564d07b018754ad5b4bfd2dc (patch)
tree9e367907bce98810e627160c892b18803d41bf23 /src
parent `failure` scaffolding (diff)
downloadwireguard-rs-f33390ebb9b8248f564d07b018754ad5b4bfd2dc.tar.xz
wireguard-rs-f33390ebb9b8248f564d07b018754ad5b4bfd2dc.zip
start replacing panics with Failure errors
Diffstat (limited to 'src')
-rw-r--r--src/error.rs3
-rw-r--r--src/interface/mod.rs2
-rw-r--r--src/interface/peer_server.rs53
-rw-r--r--src/main.rs1
-rw-r--r--src/protocol/peer.rs29
5 files changed, 49 insertions, 39 deletions
diff --git a/src/error.rs b/src/error.rs
index 49784ae..5e2a624 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,2 +1,5 @@
use failure::Error;
+//#[derive(Debug, Fail)]
+//enum WireguardError {
+//} \ No newline at end of file
diff --git a/src/interface/mod.rs b/src/interface/mod.rs
index 228ea31..5513ab2 100644
--- a/src/interface/mod.rs
+++ b/src/interface/mod.rs
@@ -113,7 +113,7 @@ impl Interface {
let (utun_tx, utun_rx) = unsync::mpsc::channel::<UtunPacket>(1024);
- let peer_server = PeerServer::bind(core.handle(), self.state.clone(), utun_tx.clone());
+ let peer_server = PeerServer::bind(core.handle(), self.state.clone(), utun_tx.clone()).unwrap();
let utun_stream = UtunStream::connect(&self.name, &core.handle()).unwrap().framed(VecUtunCodec{});
let (utun_writer, utun_reader) = utun_stream.split();
diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs
index 7e5eadc..dce84f6 100644
--- a/src/interface/peer_server.rs
+++ b/src/interface/peer_server.rs
@@ -8,6 +8,7 @@ use std::time::Duration;
use base64;
use byteorder::{ByteOrder, BigEndian, LittleEndian};
+use failure::{Error, SyncFailure};
use futures::{self, Async, Future, Stream, Sink, Poll, future, unsync, sync, stream};
use pnet::packet::ipv4::Ipv4Packet;
use pnet::packet::ipv6::Ipv6Packet;
@@ -73,12 +74,12 @@ pub struct PeerServer {
}
impl PeerServer {
- pub fn bind(handle: Handle, shared_state: SharedState, tunnel_tx: unsync::mpsc::Sender<UtunPacket>) -> Self {
- let socket = Socket::new(Domain::ipv6(), Type::dgram(), Some(Protocol::udp())).unwrap();
- socket.set_only_v6(false).unwrap();
- socket.set_nonblocking(true).unwrap();
- socket.bind(&SocketAddr::from((Ipv6Addr::unspecified(), 0)).into()).unwrap();
- let socket = UdpSocket::from_socket(socket.into_udp_socket(), &handle.clone()).unwrap();
+ pub fn bind(handle: Handle, shared_state: SharedState, tunnel_tx: unsync::mpsc::Sender<UtunPacket>) -> Result<Self, Error> {
+ let socket = Socket::new(Domain::ipv6(), Type::dgram(), Some(Protocol::udp()))?;
+ socket.set_only_v6(false)?;
+ socket.set_nonblocking(true)?;
+ socket.bind(&SocketAddr::from((Ipv6Addr::unspecified(), 0)).into())?;
+ let socket = UdpSocket::from_socket(socket.into_udp_socket(), &handle.clone())?;
let (udp_sink, udp_stream) = socket.framed(VecUdpCodec{}).split();
let (timer_tx, timer_rx) = unsync::mpsc::channel::<TimerMessage>(1024);
let (udp_tx, udp_rx) = unsync::mpsc::channel::<(SocketAddr, Vec<u8>)>(1024);
@@ -94,9 +95,9 @@ impl PeerServer {
.then(|_| Ok(()));
handle.spawn(udp_write_passthrough);
- PeerServer {
+ Ok(PeerServer {
handle, shared_state, timer, udp_stream, udp_tx, tunnel_tx, timer_tx, timer_rx, outgoing_tx, outgoing_rx
- }
+ })
}
pub fn tx(&self) -> unsync::mpsc::Sender<UtunPacket> {
@@ -108,7 +109,7 @@ impl PeerServer {
}
// TODO: create a transport packet (type 0x4) queue until a handshake has been completed
- fn handle_incoming_packet(&mut self, addr: SocketAddr, packet: Vec<u8>) {
+ fn handle_incoming_packet(&mut self, addr: SocketAddr, packet: Vec<u8>) -> Result<(), Error> {
debug!("got a UDP packet from {:?} of length {}, packet type {}", &addr, packet.len(), packet[0]);
let mut state = self.shared_state.borrow_mut();
match packet[0] {
@@ -118,25 +119,21 @@ impl PeerServer {
let mut noise = NoiseBuilder::new("Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s".parse().unwrap())
.local_private_key(&state.interface_info.private_key.expect("no private key!"))
.prologue("WireGuard v1 zx2c4 Jason@zx2c4.com".as_bytes())
- .build_responder().unwrap();
+ .build_responder()
+ .map_err(SyncFailure::new)?;
let mut timestamp = [0u8; 116];
- if let Err(_) = noise.read_message(&packet[8..116], &mut timestamp) {
- warn!("failed to parse incoming handshake");
- return;
- }
+ let _ = noise.read_message(&packet[8..116], &mut timestamp)
+ .map_err(SyncFailure::new)?;
// TODO: hacked up API until it's officially supported in snow.
let peer_ref = {
- let their_pubkey = noise.get_remote_static().expect("should have remote static key");
+ let their_pubkey = noise.get_remote_static().expect("must have remote static key");
info!("their_pubkey: {}", base64::encode(&their_pubkey[..]));
- let peer_ref = state.pubkey_map.get(&their_pubkey[..]);
- if peer_ref.is_none() {
- warn!("unknown public key received");
- return;
- }
- peer_ref.unwrap().clone()
+ let peer_ref = state.pubkey_map.get(&their_pubkey[..])
+ .ok_or_else(|| format_err!("unknown peer pubkey"))?;
+ peer_ref.clone()
};
let mut peer = peer_ref.borrow_mut();
@@ -155,7 +152,7 @@ impl PeerServer {
let response_packet = peer.get_response_packet();
self.handle.spawn(self.udp_tx.clone().send((addr.clone(), response_packet)).then(|_| Ok(())));
- let dead_session = peer.ratchet_session().unwrap();
+ let dead_session = peer.ratchet_session()?;
if let Some(session) = dead_session {
let _ = state.index_map.remove(&session.our_index);
}
@@ -168,8 +165,13 @@ impl PeerServer {
let mut peer = peer_ref.borrow_mut();
peer.sessions.next.as_mut().unwrap().their_index = their_index;
let payload_len = peer.next_noise().expect("pending noise session")
- .read_message(&packet[12..60], &mut []).unwrap();
- assert!(payload_len == 0);
+ .read_message(&packet[12..60], &mut [])
+ .map_err(SyncFailure::new)?;
+
+ if payload_len != 0 {
+ bail!("non-zero payload length in handshake response");
+ }
+
peer.ratchet_session().unwrap();
info!("got handshake response, ratcheted session.");
@@ -230,6 +232,7 @@ impl PeerServer {
},
_ => unimplemented!()
}
+ Ok(())
}
fn handle_timer(&mut self, message: TimerMessage) {
@@ -341,7 +344,7 @@ impl Future for PeerServer {
// Handle UDP packets from the outside world
loop {
match self.udp_stream.poll() {
- Ok(Async::Ready(Some((addr, packet)))) => self.handle_incoming_packet(addr, packet),
+ Ok(Async::Ready(Some((addr, packet)))) => self.handle_incoming_packet(addr, packet).unwrap(),
Ok(Async::NotReady) => break,
Ok(Async::Ready(None)) | Err(_) => return Err(()),
}
diff --git a/src/main.rs b/src/main.rs
index c2dd16e..15d5d90 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
#![feature(ip_constructors)]
#![feature(option_filter)]
+#![feature(try_trait)]
#![allow(unused_imports)]
#[macro_use] extern crate failure;
diff --git a/src/protocol/peer.rs b/src/protocol/peer.rs
index 9507afc..a2eefba 100644
--- a/src/protocol/peer.rs
+++ b/src/protocol/peer.rs
@@ -1,6 +1,7 @@
use anti_replay::AntiReplay;
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use blake2_rfc::blake2s::{Blake2s, blake2s};
+use failure::{Error, SyncFailure};
use snow::{self, NoiseBuilder};
use pnet::packet::Packet;
use pnet::packet::ip::IpNextHeaderProtocols;
@@ -104,8 +105,9 @@ impl Peer {
let _ = std::mem::replace(&mut self.sessions.next, Some(session));
}
- pub fn ratchet_session(&mut self) -> Result<Option<Session>, ()> {
- let next = std::mem::replace(&mut self.sessions.next, None).ok_or(())?;
+ pub fn ratchet_session(&mut self) -> Result<Option<Session>, Error> {
+ let next = std::mem::replace(&mut self.sessions.next, None)
+ .ok_or_else(|| format_err!("next session is missing"))?;
let next = next.into_transport_mode();
let current = std::mem::replace(&mut self.sessions.current, Some(next));
@@ -115,22 +117,23 @@ impl Peer {
Ok(dead)
}
- pub fn decrypt_transport_packet(&mut self, our_index: u32, nonce: u64, packet: &[u8]) -> Result<Vec<u8>, ()> {
+ pub fn decrypt_transport_packet(&mut self, our_index: u32, nonce: u64, packet: &[u8]) -> Result<Vec<u8>, Error> {
self.rx_bytes += packet.len() as u64;
let session = self.sessions.current.as_mut().filter(|session| session.our_index == our_index)
.or(self.sessions.past.as_mut().filter(|session| session.our_index == our_index))
- .ok_or_else(|| ())?;
-
- if session.anti_replay.check_and_update(nonce) {
- let mut raw_packet = vec![0u8; 1500];
- session.noise.set_receiving_nonce(nonce).unwrap();
- let len = session.noise.read_message(packet, &mut raw_packet).map_err(|_| ())?;
- raw_packet.truncate(len);
- Ok(raw_packet)
- } else {
- Err(())
+ .ok_or_else(|| format_err!("couldn't find available session"))?;
+
+ if !session.anti_replay.check_and_update(nonce) {
+ bail!("replayed packet received");
}
+
+ let mut raw_packet = vec![0u8; 1500];
+ session.noise.set_receiving_nonce(nonce).unwrap();
+ let len = session.noise.read_message(packet, &mut raw_packet)
+ .map_err(SyncFailure::new)?;
+ raw_packet.truncate(len);
+ Ok(raw_packet)
}
pub fn current_noise(&mut self) -> Option<&mut snow::Session> {