diff options
author | Jake McGinty <me@jake.su> | 2018-02-10 17:36:09 +0000 |
---|---|---|
committer | Jake McGinty <me@jake.su> | 2018-02-10 17:36:09 +0000 |
commit | 988ac1968736bfe0a72d70d5bddd5eb98babf76a (patch) | |
tree | df2a95f145d05e08a3cdce50176b6728600bd359 /src | |
parent | keepalive short-circuit and panic-safe (diff) | |
download | wireguard-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.rs | 13 | ||||
-rw-r--r-- | src/interface/peer_server.rs | 18 |
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 { |