diff options
-rw-r--r-- | src/interface/peer_server.rs | 20 | ||||
-rw-r--r-- | src/peer.rs | 43 | ||||
-rw-r--r-- | src/timer.rs | 1 |
3 files changed, 29 insertions, 35 deletions
diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs index c7feb73..cf868a7 100644 --- a/src/interface/peer_server.rs +++ b/src/interface/peer_server.rs @@ -1,5 +1,5 @@ -use consts::{REKEY_TIMEOUT, REJECT_AFTER_TIME, REKEY_ATTEMPT_TIME, KEEPALIVE_TIMEOUT, - STALE_SESSION_TIMEOUT, MAX_CONTENT_SIZE, WIPE_AFTER_TIME}; +use consts::{REKEY_TIMEOUT, REKEY_ATTEMPT_TIME, KEEPALIVE_TIMEOUT, STALE_SESSION_TIMEOUT, + MAX_CONTENT_SIZE, WIPE_AFTER_TIME}; use cookie; use interface::{SharedPeer, SharedState, State, UtunPacket, config}; use peer::{Peer, SessionType}; @@ -225,7 +225,6 @@ impl PeerServer { info!("handshake response received, current session now {}", our_index); self.timer.spawn_delayed(*KEEPALIVE_TIMEOUT, TimerMessage::PassiveKeepAlive(peer_ref.clone(), our_index)); - self.timer.spawn_delayed(*REJECT_AFTER_TIME, TimerMessage::Reject(peer_ref.clone(), our_index)); self.timer.spawn_delayed(*WIPE_AFTER_TIME, TimerMessage::Wipe(peer_ref.clone())); match peer.info.keepalive { @@ -272,7 +271,6 @@ impl PeerServer { let our_new_index = peer.sessions.current.as_ref().unwrap().our_index; self.timer.spawn_delayed(*KEEPALIVE_TIMEOUT, TimerMessage::PassiveKeepAlive(peer_ref.clone(), our_new_index)); - self.timer.spawn_delayed(*REJECT_AFTER_TIME, TimerMessage::Reject(peer_ref.clone(), our_new_index)); self.timer.spawn_delayed(*WIPE_AFTER_TIME, TimerMessage::Wipe(peer_ref.clone())); } (raw_packet, peer.needs_new_handshake(false)) @@ -377,20 +375,6 @@ impl PeerServer { let new_index = self.send_handshake_init(&peer_ref)?; debug!("sent handshake init (Rekey timer) ({} -> {})", our_index, new_index); }, - Reject(peer_ref, our_index) => { - let mut peer = peer_ref.borrow_mut(); - let mut state = self.shared_state.borrow_mut(); - - debug!("rejection timeout for session {}, ejecting", our_index); - - match peer.find_session(our_index) { - Some((_, SessionType::Next)) => { peer.sessions.next = None; }, - Some((_, SessionType::Current)) => { peer.sessions.current = None; }, - Some((_, SessionType::Past)) => { peer.sessions.past = None; }, - None => debug!("reject timeout for already-killed session") - } - let _ = state.index_map.remove(&our_index); - }, PassiveKeepAlive(peer_ref, our_index) => { let mut peer = peer_ref.borrow_mut(); { diff --git a/src/peer.rs b/src/peer.rs index c2168a1..086871c 100644 --- a/src/peer.rs +++ b/src/peer.rs @@ -1,7 +1,8 @@ use anti_replay::AntiReplay; use byteorder::{ByteOrder, LittleEndian}; use consts::{TRANSPORT_OVERHEAD, TRANSPORT_HEADER_SIZE, MAX_SEGMENT_SIZE, REKEY_AFTER_MESSAGES, - REKEY_AFTER_TIME, REKEY_AFTER_TIME_RECV, REJECT_AFTER_MESSAGES, PADDING_MULTIPLE}; + REKEY_AFTER_TIME, REKEY_AFTER_TIME_RECV, REJECT_AFTER_TIME, REJECT_AFTER_MESSAGES, + PADDING_MULTIPLE}; use cookie; use failure::{Error, err_msg}; use interface::UtunPacket; @@ -46,6 +47,7 @@ pub struct Session { pub our_index : u32, pub their_index : u32, pub anti_replay : AntiReplay, + pub birthday : Timestamp, pub last_sent : Timestamp, pub last_received : Timestamp, pub keepalive_sent : bool, @@ -60,6 +62,7 @@ impl Session { anti_replay : AntiReplay::default(), last_sent : Timestamp::default(), last_received : Timestamp::default(), + birthday : Timestamp::default(), keepalive_sent : false, } } @@ -72,20 +75,22 @@ impl Session { anti_replay : AntiReplay::default(), last_sent : Timestamp::default(), last_received : Timestamp::default(), + birthday : Timestamp::default(), keepalive_sent : false, } } - pub fn into_transport_mode(self) -> Session { - Session { - noise : self.noise.into_transport_mode().unwrap(), + pub fn into_transport_mode(self) -> Result<Session, Error> { + Ok(Session { + noise : self.noise.into_transport_mode()?, our_index : self.our_index, their_index : self.their_index, anti_replay : self.anti_replay, last_sent : self.last_sent, last_received : self.last_received, keepalive_sent : self.keepalive_sent, - } + birthday : self.birthday, + }) } } @@ -259,7 +264,7 @@ impl Peer { let mut next_session = Session::with_their_index(noise, index, their_index); let response_packet = self.get_response_packet(&mut next_session)?; // TODO return and dispose of killed "next" session if exists - let _ = mem::replace(&mut self.sessions.next, Some(next_session.into_transport_mode())); + let _ = mem::replace(&mut self.sessions.next, Some(next_session.into_transport_mode()?)); self.info.endpoint = Some(addr); self.last_handshake_tai64n = Some(timestamp); @@ -286,18 +291,18 @@ impl Peer { } pub fn process_incoming_handshake_response(&mut self, packet: &[u8]) -> Result<Option<u32>, Error> { - let their_index = LittleEndian::read_u32(&packet[4..]); - let mut session = mem::replace(&mut self.sessions.next, None).ok_or_else(|| err_msg("no next session"))?; - let _ = session.noise.read_message(&packet[12..60], &mut [])?; + let their_index = LittleEndian::read_u32(&packet[4..]); + let mut session = mem::replace(&mut self.sessions.next, None).ok_or_else(|| err_msg("no next session"))?; + let _ = session.noise.read_message(&packet[12..60], &mut [])?; + session = session.into_transport_mode()?; session.their_index = their_index; - - let session = session.into_transport_mode(); + session.birthday = Timestamp::now(); + self.last_handshake = Timestamp::now(); let current = mem::replace(&mut self.sessions.current, Some(session)); let dead = mem::replace(&mut self.sessions.past, current); - self.last_handshake = Timestamp::now(); Ok(dead.map(|session| session.our_index)) } @@ -310,7 +315,9 @@ impl Peer { let session_type = { let (session, session_type) = self.find_session(our_index).ok_or_else(|| err_msg("no session with index"))?; - ensure!(session.noise.is_handshake_finished(), "session is not ready for transport packets"); + ensure!(session.noise.is_handshake_finished(), "session is not ready for transport packets"); + ensure!(nonce < REJECT_AFTER_MESSAGES, "exceeded REJECT-AFTER-MESSAGES"); + ensure!(session.birthday.elapsed() < *REJECT_AFTER_TIME, "exceeded REJECT-AFTER-TIME"); session.anti_replay.update(nonce)?; session.noise.set_receiving_nonce(nonce)?; @@ -324,7 +331,7 @@ impl Peer { raw_packet.truncate(0); } - session.last_received = Timestamp::now(); + session.last_received = Timestamp::now(); session.keepalive_sent = false; // reset passive keepalive token since received a valid ingress transport session_type @@ -335,7 +342,10 @@ impl Peer { let next = std::mem::replace(&mut self.sessions.next, None); let current = std::mem::replace(&mut self.sessions.current, next); let dead = std::mem::replace(&mut self.sessions.past, current); - self.last_handshake = Timestamp::now(); + + self.sessions.current.as_mut().unwrap().birthday = Timestamp::now(); + self.last_handshake = Timestamp::now(); + Some(dead.map(|session| session.our_index)) } else { None @@ -355,7 +365,8 @@ impl Peer { let mut out_packet = vec![0u8; padded_len + TRANSPORT_OVERHEAD]; let nonce = session.noise.sending_nonce()?; - ensure!(nonce < REJECT_AFTER_MESSAGES, "exceeded maximum message count"); + ensure!(nonce < REJECT_AFTER_MESSAGES, "exceeded REJECT-AFTER-MESSAGES"); + ensure!(session.birthday.elapsed() < *REJECT_AFTER_TIME, "exceeded REJECT-AFTER-TIME"); out_packet[0] = 4; LittleEndian::write_u32(&mut out_packet[4..], session.their_index); diff --git a/src/timer.rs b/src/timer.rs index 254fa22..7db3b2e 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -10,7 +10,6 @@ pub enum TimerMessage { PersistentKeepAlive(SharedPeer, u32), PassiveKeepAlive(SharedPeer, u32), Rekey(SharedPeer, u32), - Reject(SharedPeer, u32), Wipe(SharedPeer), } |