diff options
author | Jake McGinty <me@jake.su> | 2018-02-08 17:02:20 +0000 |
---|---|---|
committer | Jake McGinty <me@jake.su> | 2018-02-08 17:02:20 +0000 |
commit | efa7c0d587aea80e8b0b3f66ffacfce7c364c40a (patch) | |
tree | d22f21d2fd2feeeb7c6fbb4b730f154a124affe0 | |
parent | bubble failures in handshake processing for peers (diff) | |
download | wireguard-rs-efa7c0d587aea80e8b0b3f66ffacfce7c364c40a.tar.xz wireguard-rs-efa7c0d587aea80e8b0b3f66ffacfce7c364c40a.zip |
make anti-replay code more canonically rust
-rw-r--r-- | src/anti_replay.rs | 39 | ||||
-rw-r--r-- | src/interface/peer_server.rs | 2 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/protocol/peer.rs | 4 | ||||
-rw-r--r-- | src/router.rs | 0 |
5 files changed, 24 insertions, 23 deletions
diff --git a/src/anti_replay.rs b/src/anti_replay.rs index e3803aa..58d490a 100644 --- a/src/anti_replay.rs +++ b/src/anti_replay.rs @@ -15,6 +15,7 @@ // You should have received a copy of the GNU General Public License // along with WireGuard.rs. If not, see <https://www.gnu.org/licenses/>. +use failure::Error; // This is RFC 6479. @@ -52,7 +53,7 @@ impl AntiReplay { /// Returns true if check is passed, i.e., not a replay or too old. /// /// Unlike RFC 6479, zero is allowed. - pub fn check(&self, seq: u64) -> bool { + fn check(&self, seq: u64) -> bool { // Larger is always good. if seq > self.last { return true; @@ -69,7 +70,7 @@ impl AntiReplay { } /// Should only be called if check returns true. - pub fn update(&mut self, seq: u64) { + fn update_store(&mut self, seq: u64) { debug_assert!(self.check(seq)); let index = seq >> REDUNDANT_BIT_SHIFTS; @@ -95,12 +96,12 @@ impl AntiReplay { self.bitmap[index as usize] |= 1 << bit_location; } - pub fn check_and_update(&mut self, seq: u64) -> bool { + pub fn update(&mut self, seq: u64) -> Result<(), Error> { if self.check(seq) { - self.update(seq); - true + self.update_store(seq); + Ok(()) } else { - false + bail!("replayed nonce") } } } @@ -114,35 +115,35 @@ mod tests { let mut ar = AntiReplay::new(); for i in 0..20000 { - assert!(ar.check_and_update(i)); + ar.update(i).unwrap(); } for i in (0..20000).rev() { assert!(!ar.check(i)); } - assert!(ar.check_and_update(65536)); + ar.update(65536).unwrap(); for i in (65536 - WINDOW_SIZE)..65535 { - assert!(ar.check_and_update(i)); + ar.update(i).unwrap(); } for i in (65536 - 10 * WINDOW_SIZE)..65535 { assert!(!ar.check(i)); } - ar.check_and_update(66000); + ar.update(66000).unwrap(); for i in 65537..66000 { - assert!(ar.check_and_update(i)); + ar.update(i).unwrap(); } for i in 65537..66000 { - assert!(!ar.check_and_update(i)); + assert!(ar.update(i).is_err()); } // Test max u64. let next = u64::max_value(); - assert!(ar.check_and_update(next)); + ar.update(next).unwrap(); assert!(!ar.check(next)); for i in (next - WINDOW_SIZE)..next { - assert!(ar.check_and_update(i)); + ar.update(i).unwrap(); } for i in (next - 20 * WINDOW_SIZE)..next { assert!(!ar.check(i)); @@ -155,7 +156,7 @@ mod tests { let mut seq = 0; b.iter(|| { - assert!(ar.check_and_update(seq)); + ar.update(seq).unwrap(); seq += 1; }); } @@ -163,11 +164,11 @@ mod tests { #[bench] fn bench_anti_replay_old(b: &mut ::test::Bencher) { let mut ar = AntiReplay::new(); - ar.check_and_update(12345); - ar.check_and_update(11234); + ar.update(12345).unwrap(); + ar.update(11234).unwrap(); b.iter(|| { - assert!(!ar.check_and_update(11234)); + assert!(ar.update(11234).is_err()); }); } @@ -177,7 +178,7 @@ mod tests { let mut seq = 0; b.iter(|| { - assert!(ar.check_and_update(seq)); + ar.update(seq).unwrap(); seq += 30000; }); } diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs index 415c78f..420332f 100644 --- a/src/interface/peer_server.rs +++ b/src/interface/peer_server.rs @@ -218,7 +218,7 @@ impl PeerServer { if let Ok(raw_packet) = res { trace_packet("received TRANSPORT: ", &raw_packet); - let utun_packet = match (raw_packet[0] & 0xf0) >> 4 { + let utun_packet = match raw_packet[0] >> 4 { 4 => UtunPacket::Inet4(raw_packet), 6 => UtunPacket::Inet6(raw_packet), _ => unimplemented!() diff --git a/src/main.rs b/src/main.rs index 15d5d90..06af127 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #![feature(ip_constructors)] #![feature(option_filter)] #![feature(try_trait)] +#![feature(test)] #![allow(unused_imports)] #[macro_use] extern crate failure; @@ -21,6 +22,7 @@ extern crate rand; extern crate snow; extern crate socket2; extern crate structopt; +extern crate test; extern crate time; extern crate tokio_core; extern crate tokio_io; diff --git a/src/protocol/peer.rs b/src/protocol/peer.rs index fc837e5..14d8691 100644 --- a/src/protocol/peer.rs +++ b/src/protocol/peer.rs @@ -124,9 +124,7 @@ impl Peer { .or(self.sessions.past.as_mut().filter(|session| session.our_index == our_index)) .ok_or_else(|| format_err!("couldn't find available session"))?; - if !session.anti_replay.check_and_update(nonce) { - bail!("replayed packet received"); - } + session.anti_replay.update(nonce)?; let mut raw_packet = vec![0u8; 1500]; session.noise.set_receiving_nonce(nonce) diff --git a/src/router.rs b/src/router.rs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/router.rs |