aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJake McGinty <me@jake.su>2018-02-10 17:36:09 +0000
committerJake McGinty <me@jake.su>2018-02-10 17:36:09 +0000
commit988ac1968736bfe0a72d70d5bddd5eb98babf76a (patch)
treedf2a95f145d05e08a3cdce50176b6728600bd359 /src
parentkeepalive short-circuit and panic-safe (diff)
downloadwireguard-rs-988ac1968736bfe0a72d70d5bddd5eb98babf76a.tar.xz
wireguard-rs-988ac1968736bfe0a72d70d5bddd5eb98babf76a.zip
don't limit message size to standard UDP MTU
Diffstat (limited to 'src')
-rw-r--r--src/consts.rs13
-rw-r--r--src/interface/peer_server.rs18
2 files changed, 19 insertions, 12 deletions
diff --git a/src/consts.rs b/src/consts.rs
index a6806ad..f5059d0 100644
--- a/src/consts.rs
+++ b/src/consts.rs
@@ -1,6 +1,5 @@
-// via Section 6.1 of the WireGuard spec draft
-
#![allow(dead_code)]
+
use std::u64;
// transport ratcheting time limits, in seconds
@@ -9,11 +8,17 @@ pub const REKEY_AFTER_TIME: u64 = 120;
pub const REJECT_AFTER_TIME: u64 = 180;
// transport ratcheting message limits, in seconds
-pub const REJECT_AFTER_MESSAGES: u64 = u64::MAX - 65537;
-pub const REKEY_AFTER_MESSAGES: u64 = u64::MAX - 17;
+pub const REJECT_AFTER_MESSAGES: u64 = u64::MAX - (1 << 16) - 1;
+pub const REKEY_AFTER_MESSAGES: u64 = u64::MAX - (1 << 4) - 1;
// how often to attempt rekeying
pub const REKEY_TIMEOUT: u64 = 5;
// keepalive packet timer, in seconds
pub const KEEPALIVE_TIMEOUT: u64 = 10;
+
+pub const TRANSPORT_HEADER_SIZE: usize = 16;
+pub const AEAD_TAG_SIZE: usize = 16;
+pub const TRANSPORT_OVERHEAD: usize = TRANSPORT_HEADER_SIZE + AEAD_TAG_SIZE;
+pub const MAX_SEGMENT_SIZE: usize = (1 << 16) - 1;
+pub const MAX_CONTENT_SIZE: usize = MAX_SEGMENT_SIZE - TRANSPORT_OVERHEAD;
diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs
index 36bbf6f..7e5114c 100644
--- a/src/interface/peer_server.rs
+++ b/src/interface/peer_server.rs
@@ -1,5 +1,5 @@
use super::{SharedState, SharedPeer, UtunPacket, trace_packet};
-use consts::{REKEY_AFTER_TIME, KEEPALIVE_TIMEOUT};
+use consts::{REKEY_AFTER_TIME, KEEPALIVE_TIMEOUT, MAX_CONTENT_SIZE, TRANSPORT_HEADER_SIZE, TRANSPORT_OVERHEAD};
use protocol::Session;
use noise::Noise;
@@ -258,7 +258,7 @@ impl PeerServer {
},
TimerMessage::KeepAlive(peer_ref, _our_index) => {
let mut peer = peer_ref.borrow_mut();
- let mut packet = vec![0u8; 1500];
+ let mut packet = vec![0u8; TRANSPORT_OVERHEAD];
packet[0] = 4;
let their_index = peer.their_current_index().expect("no current index for them");
let endpoint = peer.info.endpoint.unwrap();
@@ -266,8 +266,7 @@ impl PeerServer {
let noise = peer.current_noise().expect("current noise session");
LittleEndian::write_u32(&mut packet[4..], their_index);
LittleEndian::write_u64(&mut packet[8..], noise.sending_nonce().unwrap());
- let len = noise.write_message(&[], &mut packet[16..]).expect("failed to encrypt outgoing keepalive");
- packet.truncate(len + 16);
+ let _ = noise.write_message(&[], &mut packet[16..]).expect("failed to encrypt outgoing keepalive");
self.handle.spawn(self.udp_tx.clone().send((endpoint, packet)).then(|_| Ok(())));
debug!("sent keepalive");
}
@@ -276,17 +275,20 @@ impl PeerServer {
}
// Just this way to avoid a double-mutable-borrow while peeking.
- fn peek_and_handle(&mut self) -> Result<bool,()> {
+ fn peek_and_handle(&mut self) -> Result<bool, Error> {
let routed = {
let packet = match self.outgoing_rx.peek() {
Ok(Async::Ready(Some(packet))) => packet,
Ok(Async::NotReady) => return Ok(false),
- Ok(Async::Ready(None)) | Err(_) => return Err(()),
+ Ok(Async::Ready(None)) | Err(_) => bail!("channel failure"),
};
+ ensure!(packet.payload().len() != 0 && packet.payload().len() < MAX_CONTENT_SIZE,
+ "illegal packet size");
+
trace_packet("received UTUN packet: ", packet.payload());
let state = self.shared_state.borrow();
- let mut out_packet = vec![0u8; 1500];
+ let mut out_packet = vec![0u8; packet.payload().len() + TRANSPORT_OVERHEAD];
let peer = state.router.route_to_peer(packet.payload());
if let Some(peer) = peer {
@@ -299,7 +301,7 @@ impl PeerServer {
LittleEndian::write_u32(&mut out_packet[4..], their_index);
LittleEndian::write_u64(&mut out_packet[8..], noise.sending_nonce().unwrap());
let len = noise.write_message(&packet.payload(), &mut out_packet[16..]).expect("failed to encrypt outgoing UDP packet");
- out_packet.truncate(16 + len);
+ out_packet.truncate(TRANSPORT_HEADER_SIZE + len);
self.handle.spawn(self.udp_tx.clone().send((endpoint, out_packet)).then(|_| Ok(())));
true
} else {