From 0677c7682e0742797b4dcbb70c437f8aa9a4df97 Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Wed, 21 Oct 2020 23:09:49 +0200 Subject: [PATCH] More tests --- src/net.rs | 15 +++++++++ src/payload.rs | 83 +++++++++++++++++++++++++++++++++++--------------- src/table.rs | 33 ++++++++++++++++++++ 3 files changed, 107 insertions(+), 24 deletions(-) diff --git a/src/net.rs b/src/net.rs index b080949..296c6e9 100644 --- a/src/net.rs +++ b/src/net.rs @@ -133,3 +133,18 @@ impl Socket for MockSocket { Ok(self.address) } } + +#[cfg(feature = "bench")] +mod bench { + use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket}; + use test::Bencher; + + #[bench] + fn udp_send(b: &mut Bencher) { + let sock = UdpSocket::bind("127.0.0.1:0").unwrap(); + let data = [0; 1400]; + let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 1); + b.iter(|| sock.send_to(&data, &addr).unwrap()); + b.bytes = 1400; + } +} diff --git a/src/payload.rs b/src/payload.rs index 9503a4e..45c3d46 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -3,6 +3,7 @@ // This software is licensed under GPL-3 or newer (see LICENSE.md) use crate::{error::Error, types::Address}; +use std::io::{Cursor, Read}; pub trait Protocol: Sized { fn parse(_: &[u8]) -> Result<(Address, Address), Error>; @@ -22,32 +23,23 @@ impl Protocol for Frame { /// # Errors /// This method will fail when the given data is not a valid ethernet frame. fn parse(data: &[u8]) -> Result<(Address, Address), Error> { - if data.len() < 14 { - return Err(Error::Parse("Frame is too short")) - } - let mut pos = 0; - let dst_data = &data[pos..pos + 6]; - pos += 6; - let src_data = &data[pos..pos + 6]; - pos += 6; - if data[pos] == 0x81 && data[pos + 1] == 0x00 { - pos += 2; - if data.len() < pos + 2 { - return Err(Error::Parse("Vlan frame is too short")) - } - let mut src = [0; 16]; - let mut dst = [0; 16]; - src[0] = data[pos]; - src[1] = data[pos + 1]; - dst[0] = data[pos]; - dst[1] = data[pos + 1]; - src[2..8].copy_from_slice(src_data); - dst[2..8].copy_from_slice(dst_data); + let mut cursor = Cursor::new(data); + let mut src = [0; 16]; + let mut dst = [0; 16]; + let mut proto = [0; 2]; + cursor + .read_exact(&mut dst[..6]) + .and_then(|_| cursor.read_exact(&mut src[..6])) + .and_then(|_| cursor.read_exact(&mut proto)) + .map_err(|_| Error::Parse("Frame is too short"))?; + if proto == [0x81, 0x00] { + src.copy_within(..6, 2); + dst.copy_within(..6, 2); + cursor.read_exact(&mut src[..2]).map_err(|_| Error::Parse("Vlan frame is too short"))?; + dst[..2].copy_from_slice(&src[..2]); Ok((Address { data: src, len: 8 }, Address { data: dst, len: 8 })) } else { - let src = Address::read_from_fixed(src_data, 6)?; - let dst = Address::read_from_fixed(dst_data, 6)?; - Ok((src, dst)) + Ok((Address { data: src, len: 6 }, Address { data: dst, len: 6 })) } } } @@ -78,6 +70,25 @@ fn decode_invalid_frame() { assert!(Frame::parse(&[6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 0x81, 0x00]).is_err()); } +#[cfg(feature = "bench")] +mod bench_ethernet { + use super::*; + use test::Bencher; + + #[bench] + fn decode_ethernet(b: &mut Bencher) { + let data = [6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8]; + b.iter(|| Frame::parse(&data).unwrap()); + b.bytes = 1400; + } + + #[bench] + fn decode_ethernet_with_vlan(b: &mut Bencher) { + let data = [6, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5, 6, 0x81, 0, 4, 210, 1, 2, 3, 4, 5, 6, 7, 8]; + b.iter(|| Frame::parse(&data).unwrap()); + b.bytes = 1400; + } +} /// An IP packet dissector /// @@ -159,3 +170,27 @@ fn decode_invalid_packet() { ]) .is_err()); } + + +#[cfg(feature = "bench")] +mod bench_ip { + use super::*; + use test::Bencher; + + #[bench] + fn decode_ipv4(b: &mut Bencher) { + let data = [0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 168, 1, 1, 192, 168, 1, 2]; + b.iter(|| Packet::parse(&data).unwrap()); + b.bytes = 1400; + } + + #[bench] + fn decode_ipv6(b: &mut Bencher) { + let data = [ + 0x60, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 6, + 5, 4, 3, 2, 1 + ]; + b.iter(|| Packet::parse(&data).unwrap()); + b.bytes = 1400; + } +} diff --git a/src/table.rs b/src/table.rs index 8cd3d6a..733223d 100644 --- a/src/table.rs +++ b/src/table.rs @@ -134,3 +134,36 @@ impl ClaimTable { } // TODO: test + +#[cfg(feature = "bench")] +mod bench { + use super::*; + use crate::util::MockTimeSource; + + use test::Bencher; + use std::str::FromStr; + use smallvec::smallvec; + + #[bench] + fn lookup_warm(b: &mut Bencher) { + let mut table = ClaimTable::::new(60, 60); + let addr = Address::from_str("1.2.3.4").unwrap(); + table.cache(addr, SocketAddr::from_str("1.2.3.4:3210").unwrap()); + b.iter(|| table.lookup(addr)); + b.bytes = 1400; + } + + #[bench] + fn lookup_cold(b: &mut Bencher) { + let mut table = ClaimTable::::new(60, 60); + let addr = Address::from_str("1.2.3.4").unwrap(); + table.set_claims(SocketAddr::from_str("1.2.3.4:3210").unwrap(), smallvec![ + Range::from_str("1.2.3.4/32").unwrap() + ]); + b.iter(|| { + table.cache.clear(); + table.lookup(addr) + }); + b.bytes = 1400; + } +}