Skip to main content

boringtun_easytier/noise/
mod.rs

1// Copyright (c) 2019 Cloudflare, Inc. All rights reserved.
2// SPDX-License-Identifier: BSD-3-Clause
3
4pub mod errors;
5pub mod handshake;
6pub mod rate_limiter;
7
8mod session;
9mod timers;
10
11use crate::noise::errors::WireGuardError;
12use crate::noise::handshake::Handshake;
13use crate::noise::rate_limiter::RateLimiter;
14use crate::noise::timers::{TimerName, Timers};
15use crate::x25519;
16
17use std::collections::VecDeque;
18use std::convert::{TryFrom, TryInto};
19use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
20use std::sync::Arc;
21use std::time::Duration;
22
23/// The default value to use for rate limiting, when no other rate limiter is defined
24const PEER_HANDSHAKE_RATE_LIMIT: u64 = 10;
25
26const IPV4_MIN_HEADER_SIZE: usize = 20;
27const IPV4_LEN_OFF: usize = 2;
28const IPV4_SRC_IP_OFF: usize = 12;
29const IPV4_DST_IP_OFF: usize = 16;
30const IPV4_IP_SZ: usize = 4;
31
32const IPV6_MIN_HEADER_SIZE: usize = 40;
33const IPV6_LEN_OFF: usize = 4;
34const IPV6_SRC_IP_OFF: usize = 8;
35const IPV6_DST_IP_OFF: usize = 24;
36const IPV6_IP_SZ: usize = 16;
37
38const IP_LEN_SZ: usize = 2;
39
40const MAX_QUEUE_DEPTH: usize = 256;
41/// number of sessions in the ring, better keep a PoT
42const N_SESSIONS: usize = 8;
43
44#[derive(Debug)]
45pub enum TunnResult<'a> {
46    Done,
47    Err(WireGuardError),
48    WriteToNetwork(&'a mut [u8]),
49    WriteToTunnelV4(&'a mut [u8], Ipv4Addr),
50    WriteToTunnelV6(&'a mut [u8], Ipv6Addr),
51}
52
53impl<'a> From<WireGuardError> for TunnResult<'a> {
54    fn from(err: WireGuardError) -> TunnResult<'a> {
55        TunnResult::Err(err)
56    }
57}
58
59/// Tunnel represents a point-to-point WireGuard connection
60pub struct Tunn {
61    /// The handshake currently in progress
62    handshake: handshake::Handshake,
63    /// The N_SESSIONS most recent sessions, index is session id modulo N_SESSIONS
64    sessions: [Option<session::Session>; N_SESSIONS],
65    /// Index of most recently used session
66    current: usize,
67    /// Queue to store blocked packets
68    packet_queue: VecDeque<Vec<u8>>,
69    /// Keeps tabs on the expiring timers
70    timers: timers::Timers,
71    tx_bytes: usize,
72    rx_bytes: usize,
73    rate_limiter: Arc<RateLimiter>,
74}
75
76type MessageType = u32;
77const HANDSHAKE_INIT: MessageType = 1;
78const HANDSHAKE_RESP: MessageType = 2;
79const COOKIE_REPLY: MessageType = 3;
80const DATA: MessageType = 4;
81
82const HANDSHAKE_INIT_SZ: usize = 148;
83const HANDSHAKE_RESP_SZ: usize = 92;
84const COOKIE_REPLY_SZ: usize = 64;
85const DATA_OVERHEAD_SZ: usize = 32;
86
87#[derive(Debug)]
88pub struct HandshakeInit<'a> {
89    sender_idx: u32,
90    unencrypted_ephemeral: &'a [u8; 32],
91    encrypted_static: &'a [u8],
92    encrypted_timestamp: &'a [u8],
93}
94
95#[derive(Debug)]
96pub struct HandshakeResponse<'a> {
97    sender_idx: u32,
98    pub receiver_idx: u32,
99    unencrypted_ephemeral: &'a [u8; 32],
100    encrypted_nothing: &'a [u8],
101}
102
103#[derive(Debug)]
104pub struct PacketCookieReply<'a> {
105    pub receiver_idx: u32,
106    nonce: &'a [u8],
107    encrypted_cookie: &'a [u8],
108}
109
110#[derive(Debug)]
111pub struct PacketData<'a> {
112    pub receiver_idx: u32,
113    counter: u64,
114    encrypted_encapsulated_packet: &'a [u8],
115}
116
117/// Describes a packet from network
118#[derive(Debug)]
119pub enum Packet<'a> {
120    HandshakeInit(HandshakeInit<'a>),
121    HandshakeResponse(HandshakeResponse<'a>),
122    PacketCookieReply(PacketCookieReply<'a>),
123    PacketData(PacketData<'a>),
124}
125
126impl Tunn {
127    #[inline(always)]
128    pub fn parse_incoming_packet(src: &[u8]) -> Result<Packet, WireGuardError> {
129        if src.len() < 4 {
130            return Err(WireGuardError::InvalidPacket);
131        }
132
133        // Checks the type, as well as the reserved zero fields
134        let packet_type = u32::from_le_bytes(src[0..4].try_into().unwrap());
135
136        Ok(match (packet_type, src.len()) {
137            (HANDSHAKE_INIT, HANDSHAKE_INIT_SZ) => Packet::HandshakeInit(HandshakeInit {
138                sender_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()),
139                unencrypted_ephemeral: <&[u8; 32] as TryFrom<&[u8]>>::try_from(&src[8..40])
140                    .expect("length already checked above"),
141                encrypted_static: &src[40..88],
142                encrypted_timestamp: &src[88..116],
143            }),
144            (HANDSHAKE_RESP, HANDSHAKE_RESP_SZ) => Packet::HandshakeResponse(HandshakeResponse {
145                sender_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()),
146                receiver_idx: u32::from_le_bytes(src[8..12].try_into().unwrap()),
147                unencrypted_ephemeral: <&[u8; 32] as TryFrom<&[u8]>>::try_from(&src[12..44])
148                    .expect("length already checked above"),
149                encrypted_nothing: &src[44..60],
150            }),
151            (COOKIE_REPLY, COOKIE_REPLY_SZ) => Packet::PacketCookieReply(PacketCookieReply {
152                receiver_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()),
153                nonce: &src[8..32],
154                encrypted_cookie: &src[32..64],
155            }),
156            (DATA, DATA_OVERHEAD_SZ..=std::usize::MAX) => Packet::PacketData(PacketData {
157                receiver_idx: u32::from_le_bytes(src[4..8].try_into().unwrap()),
158                counter: u64::from_le_bytes(src[8..16].try_into().unwrap()),
159                encrypted_encapsulated_packet: &src[16..],
160            }),
161            _ => return Err(WireGuardError::InvalidPacket),
162        })
163    }
164
165    pub fn is_expired(&self) -> bool {
166        self.handshake.is_expired()
167    }
168
169    pub fn dst_address(packet: &[u8]) -> Option<IpAddr> {
170        if packet.is_empty() {
171            return None;
172        }
173
174        match packet[0] >> 4 {
175            4 if packet.len() >= IPV4_MIN_HEADER_SIZE => {
176                let addr_bytes: [u8; IPV4_IP_SZ] = packet
177                    [IPV4_DST_IP_OFF..IPV4_DST_IP_OFF + IPV4_IP_SZ]
178                    .try_into()
179                    .unwrap();
180                Some(IpAddr::from(addr_bytes))
181            }
182            6 if packet.len() >= IPV6_MIN_HEADER_SIZE => {
183                let addr_bytes: [u8; IPV6_IP_SZ] = packet
184                    [IPV6_DST_IP_OFF..IPV6_DST_IP_OFF + IPV6_IP_SZ]
185                    .try_into()
186                    .unwrap();
187                Some(IpAddr::from(addr_bytes))
188            }
189            _ => None,
190        }
191    }
192
193    /// Create a new tunnel using own private key and the peer public key
194    pub fn new(
195        static_private: x25519::StaticSecret,
196        peer_static_public: x25519::PublicKey,
197        preshared_key: Option<[u8; 32]>,
198        persistent_keepalive: Option<u16>,
199        index: u32,
200        rate_limiter: Option<Arc<RateLimiter>>,
201    ) -> Self {
202        let static_public = x25519::PublicKey::from(&static_private);
203
204        Tunn {
205            handshake: Handshake::new(
206                static_private,
207                static_public,
208                peer_static_public,
209                index << 8,
210                preshared_key,
211            ),
212            sessions: Default::default(),
213            current: Default::default(),
214            tx_bytes: Default::default(),
215            rx_bytes: Default::default(),
216
217            packet_queue: VecDeque::new(),
218            timers: Timers::new(persistent_keepalive, rate_limiter.is_none()),
219
220            rate_limiter: rate_limiter.unwrap_or_else(|| {
221                Arc::new(RateLimiter::new(&static_public, PEER_HANDSHAKE_RATE_LIMIT))
222            }),
223        }
224    }
225
226    /// Update the private key and clear existing sessions
227    pub fn set_static_private(
228        &mut self,
229        static_private: x25519::StaticSecret,
230        static_public: x25519::PublicKey,
231        rate_limiter: Option<Arc<RateLimiter>>,
232    ) {
233        self.timers.should_reset_rr = rate_limiter.is_none();
234        self.rate_limiter = rate_limiter.unwrap_or_else(|| {
235            Arc::new(RateLimiter::new(&static_public, PEER_HANDSHAKE_RATE_LIMIT))
236        });
237        self.handshake
238            .set_static_private(static_private, static_public);
239        for s in &mut self.sessions {
240            *s = None;
241        }
242    }
243
244    /// Encapsulate a single packet from the tunnel interface.
245    /// Returns TunnResult.
246    ///
247    /// # Panics
248    /// Panics if dst buffer is too small.
249    /// Size of dst should be at least src.len() + 32, and no less than 148 bytes.
250    pub fn encapsulate<'a>(&mut self, src: &[u8], dst: &'a mut [u8]) -> TunnResult<'a> {
251        let current = self.current;
252        if let Some(ref session) = self.sessions[current % N_SESSIONS] {
253            // Send the packet using an established session
254            let packet = session.format_packet_data(src, dst);
255            self.timer_tick(TimerName::TimeLastPacketSent);
256            // Exclude Keepalive packets from timer update.
257            if !src.is_empty() {
258                self.timer_tick(TimerName::TimeLastDataPacketSent);
259            }
260            self.tx_bytes += src.len();
261            return TunnResult::WriteToNetwork(packet);
262        }
263
264        // If there is no session, queue the packet for future retry
265        self.queue_packet(src);
266        // Initiate a new handshake if none is in progress
267        self.format_handshake_initiation(dst, false)
268    }
269
270    /// Receives a UDP datagram from the network and parses it.
271    /// Returns TunnResult.
272    ///
273    /// If the result is of type TunnResult::WriteToNetwork, should repeat the call with empty datagram,
274    /// until TunnResult::Done is returned. If batch processing packets, it is OK to defer until last
275    /// packet is processed.
276    pub fn decapsulate<'a>(
277        &mut self,
278        src_addr: Option<IpAddr>,
279        datagram: &[u8],
280        dst: &'a mut [u8],
281    ) -> TunnResult<'a> {
282        if datagram.is_empty() {
283            // Indicates a repeated call
284            return self.send_queued_packet(dst);
285        }
286
287        let mut cookie = [0u8; COOKIE_REPLY_SZ];
288        let packet = match self
289            .rate_limiter
290            .verify_packet(src_addr, datagram, &mut cookie)
291        {
292            Ok(packet) => packet,
293            Err(TunnResult::WriteToNetwork(cookie)) => {
294                dst[..cookie.len()].copy_from_slice(cookie);
295                return TunnResult::WriteToNetwork(&mut dst[..cookie.len()]);
296            }
297            Err(TunnResult::Err(e)) => return TunnResult::Err(e),
298            _ => unreachable!(),
299        };
300
301        self.handle_verified_packet(packet, dst)
302    }
303
304    pub(crate) fn handle_verified_packet<'a>(
305        &mut self,
306        packet: Packet,
307        dst: &'a mut [u8],
308    ) -> TunnResult<'a> {
309        match packet {
310            Packet::HandshakeInit(p) => self.handle_handshake_init(p, dst),
311            Packet::HandshakeResponse(p) => self.handle_handshake_response(p, dst),
312            Packet::PacketCookieReply(p) => self.handle_cookie_reply(p),
313            Packet::PacketData(p) => self.handle_data(p, dst),
314        }
315        .unwrap_or_else(TunnResult::from)
316    }
317
318    fn handle_handshake_init<'a>(
319        &mut self,
320        p: HandshakeInit,
321        dst: &'a mut [u8],
322    ) -> Result<TunnResult<'a>, WireGuardError> {
323        tracing::debug!(
324            message = "Received handshake_initiation",
325            remote_idx = p.sender_idx
326        );
327
328        let (packet, session) = self.handshake.receive_handshake_initialization(p, dst)?;
329
330        // Store new session in ring buffer
331        let index = session.local_index();
332        self.sessions[index % N_SESSIONS] = Some(session);
333
334        self.timer_tick(TimerName::TimeLastPacketReceived);
335        self.timer_tick(TimerName::TimeLastPacketSent);
336        self.timer_tick_session_established(false, index); // New session established, we are not the initiator
337
338        tracing::debug!(message = "Sending handshake_response", local_idx = index);
339
340        Ok(TunnResult::WriteToNetwork(packet))
341    }
342
343    fn handle_handshake_response<'a>(
344        &mut self,
345        p: HandshakeResponse,
346        dst: &'a mut [u8],
347    ) -> Result<TunnResult<'a>, WireGuardError> {
348        tracing::debug!(
349            message = "Received handshake_response",
350            local_idx = p.receiver_idx,
351            remote_idx = p.sender_idx
352        );
353
354        let session = self.handshake.receive_handshake_response(p)?;
355
356        let keepalive_packet = session.format_packet_data(&[], dst);
357        // Store new session in ring buffer
358        let l_idx = session.local_index();
359        let index = l_idx % N_SESSIONS;
360        self.sessions[index] = Some(session);
361
362        self.timer_tick(TimerName::TimeLastPacketReceived);
363        self.timer_tick_session_established(true, index); // New session established, we are the initiator
364        self.set_current_session(l_idx);
365
366        tracing::debug!("Sending keepalive");
367
368        Ok(TunnResult::WriteToNetwork(keepalive_packet)) // Send a keepalive as a response
369    }
370
371    fn handle_cookie_reply<'a>(
372        &mut self,
373        p: PacketCookieReply,
374    ) -> Result<TunnResult<'a>, WireGuardError> {
375        tracing::debug!(
376            message = "Received cookie_reply",
377            local_idx = p.receiver_idx
378        );
379
380        self.handshake.receive_cookie_reply(p)?;
381        self.timer_tick(TimerName::TimeLastPacketReceived);
382        self.timer_tick(TimerName::TimeCookieReceived);
383
384        tracing::debug!("Did set cookie");
385
386        Ok(TunnResult::Done)
387    }
388
389    /// Update the index of the currently used session, if needed
390    fn set_current_session(&mut self, new_idx: usize) {
391        let cur_idx = self.current;
392        if cur_idx == new_idx {
393            // There is nothing to do, already using this session, this is the common case
394            return;
395        }
396        if self.sessions[cur_idx % N_SESSIONS].is_none()
397            || self.timers.session_timers[new_idx % N_SESSIONS]
398                >= self.timers.session_timers[cur_idx % N_SESSIONS]
399        {
400            self.current = new_idx;
401            tracing::debug!(message = "New session", session = new_idx);
402        }
403    }
404
405    /// Decrypts a data packet, and stores the decapsulated packet in dst.
406    fn handle_data<'a>(
407        &mut self,
408        packet: PacketData,
409        dst: &'a mut [u8],
410    ) -> Result<TunnResult<'a>, WireGuardError> {
411        let r_idx = packet.receiver_idx as usize;
412        let idx = r_idx % N_SESSIONS;
413
414        // Get the (probably) right session
415        let decapsulated_packet = {
416            let session = self.sessions[idx].as_ref();
417            let session = session.ok_or_else(|| {
418                tracing::trace!(message = "No current session available", remote_idx = r_idx);
419                WireGuardError::NoCurrentSession
420            })?;
421            session.receive_packet_data(packet, dst)?
422        };
423
424        self.set_current_session(r_idx);
425
426        self.timer_tick(TimerName::TimeLastPacketReceived);
427
428        Ok(self.validate_decapsulated_packet(decapsulated_packet))
429    }
430
431    /// Formats a new handshake initiation message and store it in dst. If force_resend is true will send
432    /// a new handshake, even if a handshake is already in progress (for example when a handshake times out)
433    pub fn format_handshake_initiation<'a>(
434        &mut self,
435        dst: &'a mut [u8],
436        force_resend: bool,
437    ) -> TunnResult<'a> {
438        if self.handshake.is_in_progress() && !force_resend {
439            return TunnResult::Done;
440        }
441
442        if self.handshake.is_expired() {
443            self.timers.clear();
444        }
445
446        let starting_new_handshake = !self.handshake.is_in_progress();
447
448        match self.handshake.format_handshake_initiation(dst) {
449            Ok(packet) => {
450                tracing::debug!("Sending handshake_initiation");
451
452                if starting_new_handshake {
453                    self.timer_tick(TimerName::TimeLastHandshakeStarted);
454                }
455                self.timer_tick(TimerName::TimeLastPacketSent);
456                TunnResult::WriteToNetwork(packet)
457            }
458            Err(e) => TunnResult::Err(e),
459        }
460    }
461
462    /// Check if an IP packet is v4 or v6, truncate to the length indicated by the length field
463    /// Returns the truncated packet and the source IP as TunnResult
464    fn validate_decapsulated_packet<'a>(&mut self, packet: &'a mut [u8]) -> TunnResult<'a> {
465        let (computed_len, src_ip_address) = match packet.len() {
466            0 => return TunnResult::Done, // This is keepalive, and not an error
467            _ if packet[0] >> 4 == 4 && packet.len() >= IPV4_MIN_HEADER_SIZE => {
468                let len_bytes: [u8; IP_LEN_SZ] = packet[IPV4_LEN_OFF..IPV4_LEN_OFF + IP_LEN_SZ]
469                    .try_into()
470                    .unwrap();
471                let addr_bytes: [u8; IPV4_IP_SZ] = packet
472                    [IPV4_SRC_IP_OFF..IPV4_SRC_IP_OFF + IPV4_IP_SZ]
473                    .try_into()
474                    .unwrap();
475                (
476                    u16::from_be_bytes(len_bytes) as usize,
477                    IpAddr::from(addr_bytes),
478                )
479            }
480            _ if packet[0] >> 4 == 6 && packet.len() >= IPV6_MIN_HEADER_SIZE => {
481                let len_bytes: [u8; IP_LEN_SZ] = packet[IPV6_LEN_OFF..IPV6_LEN_OFF + IP_LEN_SZ]
482                    .try_into()
483                    .unwrap();
484                let addr_bytes: [u8; IPV6_IP_SZ] = packet
485                    [IPV6_SRC_IP_OFF..IPV6_SRC_IP_OFF + IPV6_IP_SZ]
486                    .try_into()
487                    .unwrap();
488                (
489                    u16::from_be_bytes(len_bytes) as usize + IPV6_MIN_HEADER_SIZE,
490                    IpAddr::from(addr_bytes),
491                )
492            }
493            _ => return TunnResult::Err(WireGuardError::InvalidPacket),
494        };
495
496        if computed_len > packet.len() {
497            return TunnResult::Err(WireGuardError::InvalidPacket);
498        }
499
500        self.timer_tick(TimerName::TimeLastDataPacketReceived);
501        self.rx_bytes += computed_len;
502
503        match src_ip_address {
504            IpAddr::V4(addr) => TunnResult::WriteToTunnelV4(&mut packet[..computed_len], addr),
505            IpAddr::V6(addr) => TunnResult::WriteToTunnelV6(&mut packet[..computed_len], addr),
506        }
507    }
508
509    /// Get a packet from the queue, and try to encapsulate it
510    fn send_queued_packet<'a>(&mut self, dst: &'a mut [u8]) -> TunnResult<'a> {
511        if let Some(packet) = self.dequeue_packet() {
512            match self.encapsulate(&packet, dst) {
513                TunnResult::Err(_) => {
514                    // On error, return packet to the queue
515                    self.requeue_packet(packet);
516                }
517                r => return r,
518            }
519        }
520        TunnResult::Done
521    }
522
523    /// Push packet to the back of the queue
524    fn queue_packet(&mut self, packet: &[u8]) {
525        if self.packet_queue.len() < MAX_QUEUE_DEPTH {
526            // Drop if too many are already in queue
527            self.packet_queue.push_back(packet.to_vec());
528        }
529    }
530
531    /// Push packet to the front of the queue
532    fn requeue_packet(&mut self, packet: Vec<u8>) {
533        if self.packet_queue.len() < MAX_QUEUE_DEPTH {
534            // Drop if too many are already in queue
535            self.packet_queue.push_front(packet);
536        }
537    }
538
539    fn dequeue_packet(&mut self) -> Option<Vec<u8>> {
540        self.packet_queue.pop_front()
541    }
542
543    fn estimate_loss(&self) -> f32 {
544        let session_idx = self.current;
545
546        let mut weight = 9.0;
547        let mut cur_avg = 0.0;
548        let mut total_weight = 0.0;
549
550        for i in 0..N_SESSIONS {
551            if let Some(ref session) = self.sessions[(session_idx.wrapping_sub(i)) % N_SESSIONS] {
552                let (expected, received) = session.current_packet_cnt();
553
554                let loss = if expected == 0 {
555                    0.0
556                } else {
557                    1.0 - received as f32 / expected as f32
558                };
559
560                cur_avg += loss * weight;
561                total_weight += weight;
562                weight /= 3.0;
563            }
564        }
565
566        if total_weight == 0.0 {
567            0.0
568        } else {
569            cur_avg / total_weight
570        }
571    }
572
573    /// Return stats from the tunnel:
574    /// * Time since last handshake in seconds
575    /// * Data bytes sent
576    /// * Data bytes received
577    pub fn stats(&self) -> (Option<Duration>, usize, usize, f32, Option<u32>) {
578        let time = self.time_since_last_handshake();
579        let tx_bytes = self.tx_bytes;
580        let rx_bytes = self.rx_bytes;
581        let loss = self.estimate_loss();
582        let rtt = self.handshake.last_rtt;
583
584        (time, tx_bytes, rx_bytes, loss, rtt)
585    }
586}
587
588#[cfg(test)]
589mod tests {
590    #[cfg(feature = "mock-instant")]
591    use crate::noise::timers::{REKEY_AFTER_TIME, REKEY_TIMEOUT};
592
593    use super::*;
594    use rand_core::{OsRng, RngCore};
595
596    fn create_two_tuns() -> (Tunn, Tunn) {
597        let my_secret_key = x25519_dalek::StaticSecret::random_from_rng(OsRng);
598        let my_public_key = x25519_dalek::PublicKey::from(&my_secret_key);
599        let my_idx = OsRng.next_u32();
600
601        let their_secret_key = x25519_dalek::StaticSecret::random_from_rng(OsRng);
602        let their_public_key = x25519_dalek::PublicKey::from(&their_secret_key);
603        let their_idx = OsRng.next_u32();
604
605        let my_tun = Tunn::new(my_secret_key, their_public_key, None, None, my_idx, None);
606
607        let their_tun = Tunn::new(their_secret_key, my_public_key, None, None, their_idx, None);
608
609        (my_tun, their_tun)
610    }
611
612    fn create_handshake_init(tun: &mut Tunn) -> Vec<u8> {
613        let mut dst = vec![0u8; 2048];
614        let handshake_init = tun.format_handshake_initiation(&mut dst, false);
615        assert!(matches!(handshake_init, TunnResult::WriteToNetwork(_)));
616        let handshake_init = if let TunnResult::WriteToNetwork(sent) = handshake_init {
617            sent
618        } else {
619            unreachable!();
620        };
621
622        handshake_init.into()
623    }
624
625    fn create_handshake_response(tun: &mut Tunn, handshake_init: &[u8]) -> Vec<u8> {
626        let mut dst = vec![0u8; 2048];
627        let handshake_resp = tun.decapsulate(None, handshake_init, &mut dst);
628        assert!(matches!(handshake_resp, TunnResult::WriteToNetwork(_)));
629
630        let handshake_resp = if let TunnResult::WriteToNetwork(sent) = handshake_resp {
631            sent
632        } else {
633            unreachable!();
634        };
635
636        handshake_resp.into()
637    }
638
639    fn parse_handshake_resp(tun: &mut Tunn, handshake_resp: &[u8]) -> Vec<u8> {
640        let mut dst = vec![0u8; 2048];
641        let keepalive = tun.decapsulate(None, handshake_resp, &mut dst);
642        assert!(matches!(keepalive, TunnResult::WriteToNetwork(_)));
643
644        let keepalive = if let TunnResult::WriteToNetwork(sent) = keepalive {
645            sent
646        } else {
647            unreachable!();
648        };
649
650        keepalive.into()
651    }
652
653    fn parse_keepalive(tun: &mut Tunn, keepalive: &[u8]) {
654        let mut dst = vec![0u8; 2048];
655        let keepalive = tun.decapsulate(None, keepalive, &mut dst);
656        assert!(matches!(keepalive, TunnResult::Done));
657    }
658
659    fn create_two_tuns_and_handshake() -> (Tunn, Tunn) {
660        let (mut my_tun, mut their_tun) = create_two_tuns();
661        let init = create_handshake_init(&mut my_tun);
662        let resp = create_handshake_response(&mut their_tun, &init);
663        let keepalive = parse_handshake_resp(&mut my_tun, &resp);
664        parse_keepalive(&mut their_tun, &keepalive);
665
666        (my_tun, their_tun)
667    }
668
669    fn create_ipv4_udp_packet() -> Vec<u8> {
670        let header =
671            etherparse::PacketBuilder::ipv4([192, 168, 1, 2], [192, 168, 1, 3], 5).udp(5678, 23);
672        let payload = [0, 1, 2, 3];
673        let mut packet = Vec::<u8>::with_capacity(header.size(payload.len()));
674        header.write(&mut packet, &payload).unwrap();
675        packet
676    }
677
678    #[cfg(feature = "mock-instant")]
679    fn update_timer_results_in_handshake(tun: &mut Tunn) {
680        let mut dst = vec![0u8; 2048];
681        let result = tun.update_timers(&mut dst);
682        assert!(matches!(result, TunnResult::WriteToNetwork(_)));
683        let packet_data = if let TunnResult::WriteToNetwork(data) = result {
684            data
685        } else {
686            unreachable!();
687        };
688        let packet = Tunn::parse_incoming_packet(packet_data).unwrap();
689        assert!(matches!(packet, Packet::HandshakeInit(_)));
690    }
691
692    #[test]
693    fn create_two_tunnels_linked_to_eachother() {
694        let (_my_tun, _their_tun) = create_two_tuns();
695    }
696
697    #[test]
698    fn handshake_init() {
699        let (mut my_tun, _their_tun) = create_two_tuns();
700        let init = create_handshake_init(&mut my_tun);
701        let packet = Tunn::parse_incoming_packet(&init).unwrap();
702        assert!(matches!(packet, Packet::HandshakeInit(_)));
703    }
704
705    #[test]
706    fn handshake_init_and_response() {
707        let (mut my_tun, mut their_tun) = create_two_tuns();
708        let init = create_handshake_init(&mut my_tun);
709        let resp = create_handshake_response(&mut their_tun, &init);
710        let packet = Tunn::parse_incoming_packet(&resp).unwrap();
711        assert!(matches!(packet, Packet::HandshakeResponse(_)));
712    }
713
714    #[test]
715    fn full_handshake() {
716        let (mut my_tun, mut their_tun) = create_two_tuns();
717        let init = create_handshake_init(&mut my_tun);
718        let resp = create_handshake_response(&mut their_tun, &init);
719        let keepalive = parse_handshake_resp(&mut my_tun, &resp);
720        let packet = Tunn::parse_incoming_packet(&keepalive).unwrap();
721        assert!(matches!(packet, Packet::PacketData(_)));
722    }
723
724    #[test]
725    fn full_handshake_plus_timers() {
726        let (mut my_tun, mut their_tun) = create_two_tuns_and_handshake();
727        // Time has not yet advanced so their is nothing to do
728        assert!(matches!(my_tun.update_timers(&mut []), TunnResult::Done));
729        assert!(matches!(their_tun.update_timers(&mut []), TunnResult::Done));
730    }
731
732    #[test]
733    #[cfg(feature = "mock-instant")]
734    fn new_handshake_after_two_mins() {
735        let (mut my_tun, mut their_tun) = create_two_tuns_and_handshake();
736        let mut my_dst = [0u8; 1024];
737
738        // Advance time 1 second and "send" 1 packet so that we send a handshake
739        // after the timeout
740        mock_instant::MockClock::advance(Duration::from_secs(1));
741        assert!(matches!(their_tun.update_timers(&mut []), TunnResult::Done));
742        assert!(matches!(
743            my_tun.update_timers(&mut my_dst),
744            TunnResult::Done
745        ));
746        let sent_packet_buf = create_ipv4_udp_packet();
747        let data = my_tun.encapsulate(&sent_packet_buf, &mut my_dst);
748        assert!(matches!(data, TunnResult::WriteToNetwork(_)));
749
750        //Advance to timeout
751        mock_instant::MockClock::advance(REKEY_AFTER_TIME);
752        assert!(matches!(their_tun.update_timers(&mut []), TunnResult::Done));
753        update_timer_results_in_handshake(&mut my_tun);
754    }
755
756    #[test]
757    #[cfg(feature = "mock-instant")]
758    fn handshake_no_resp_rekey_timeout() {
759        let (mut my_tun, _their_tun) = create_two_tuns();
760
761        let init = create_handshake_init(&mut my_tun);
762        let packet = Tunn::parse_incoming_packet(&init).unwrap();
763        assert!(matches!(packet, Packet::HandshakeInit(_)));
764
765        mock_instant::MockClock::advance(REKEY_TIMEOUT);
766        update_timer_results_in_handshake(&mut my_tun)
767    }
768
769    #[test]
770    fn one_ip_packet() {
771        let (mut my_tun, mut their_tun) = create_two_tuns_and_handshake();
772        let mut my_dst = [0u8; 1024];
773        let mut their_dst = [0u8; 1024];
774
775        let sent_packet_buf = create_ipv4_udp_packet();
776
777        let data = my_tun.encapsulate(&sent_packet_buf, &mut my_dst);
778        assert!(matches!(data, TunnResult::WriteToNetwork(_)));
779        let data = if let TunnResult::WriteToNetwork(sent) = data {
780            sent
781        } else {
782            unreachable!();
783        };
784
785        let data = their_tun.decapsulate(None, data, &mut their_dst);
786        assert!(matches!(data, TunnResult::WriteToTunnelV4(..)));
787        let recv_packet_buf = if let TunnResult::WriteToTunnelV4(recv, _addr) = data {
788            recv
789        } else {
790            unreachable!();
791        };
792        assert_eq!(sent_packet_buf, recv_packet_buf);
793    }
794}