Compare commits

...

4 Commits

Author SHA1 Message Date
Dennis Schwerdel 7e8b042055 treat vlan id 0x000 as untagged 2020-10-21 23:42:03 +02:00
Dennis Schwerdel 28d26830c9 treat vlan id 0x000 as untagged 2020-10-21 23:41:33 +02:00
Dennis Schwerdel 2656820f37 Ignore first 4 bits of VLAN header 2020-10-21 23:32:59 +02:00
Dennis Schwerdel 0677c7682e More tests 2020-10-21 23:09:49 +02:00
4 changed files with 278 additions and 23 deletions

View File

@ -0,0 +1,165 @@
{
"meta": {
"region": "eu-central-1",
"instance_type": "m5.large",
"ami": "ami-00a205cb8e06c3c4e",
"version": "2.0-pre",
"duration": 621.4215319156647
},
"native": {
"iperf": {
"throughput": 9680424000.0,
"cpu_sender": 12.878548,
"cpu_receiver": 66.330665
},
"ping_100": {
"rtt_min": 0.045,
"rtt_max": 0.204,
"rtt_avg": 0.052,
"pkt_loss": 0.0
},
"ping_500": {
"rtt_min": 0.047,
"rtt_max": 0.213,
"rtt_avg": 0.054,
"pkt_loss": 0.0
},
"ping_1000": {
"rtt_min": 0.048,
"rtt_max": 0.629,
"rtt_avg": 0.055,
"pkt_loss": 0.0
}
},
"plain": {
"iperf": {
"throughput": 5733394000.0,
"cpu_sender": 11.835632,
"cpu_receiver": 67.865656
},
"ping_100": {
"rtt_min": 0.074,
"rtt_max": 3.375,
"rtt_avg": 0.093,
"pkt_loss": 0.0
},
"ping_500": {
"rtt_min": 0.076,
"rtt_max": 1.886,
"rtt_avg": 0.095,
"pkt_loss": 0.0
},
"ping_1000": {
"rtt_min": 0.076,
"rtt_max": 1.873,
"rtt_avg": 0.094,
"pkt_loss": 0.0
}
},
"aes256": {
"iperf": {
"throughput": 3917323000.0,
"cpu_sender": 7.746875,
"cpu_receiver": 65.508621
},
"ping_100": {
"rtt_min": 0.076,
"rtt_max": 1.527,
"rtt_avg": 0.093,
"pkt_loss": 0.0
},
"ping_500": {
"rtt_min": 0.075,
"rtt_max": 1.969,
"rtt_avg": 0.094,
"pkt_loss": 0.0
},
"ping_1000": {
"rtt_min": 0.079,
"rtt_max": 1.973,
"rtt_avg": 0.096,
"pkt_loss": 0.0
}
},
"aes128": {
"iperf": {
"throughput": 3899771000.0,
"cpu_sender": 6.73498,
"cpu_receiver": 64.197019
},
"ping_100": {
"rtt_min": 0.073,
"rtt_max": 1.522,
"rtt_avg": 0.094,
"pkt_loss": 0.0
},
"ping_500": {
"rtt_min": 0.08,
"rtt_max": 1.979,
"rtt_avg": 0.098,
"pkt_loss": 0.0
},
"ping_1000": {
"rtt_min": 0.082,
"rtt_max": 2.162,
"rtt_avg": 0.099,
"pkt_loss": 0.0
}
},
"chacha20": {
"iperf": {
"throughput": 2888735000.0,
"cpu_sender": 6.548527,
"cpu_receiver": 63.424257
},
"ping_100": {
"rtt_min": 0.078,
"rtt_max": 0.276,
"rtt_avg": 0.095,
"pkt_loss": 0.0
},
"ping_500": {
"rtt_min": 0.084,
"rtt_max": 0.241,
"rtt_avg": 0.1,
"pkt_loss": 0.0
},
"ping_1000": {
"rtt_min": 0.087,
"rtt_max": 0.424,
"rtt_avg": 0.106,
"pkt_loss": 0.0
}
},
"results": {
"throughput_mbits": {
"native": 9680.424,
"plain": 5733.394,
"aes256": 3917.323,
"aes128": 3899.771,
"chacha20": 2888.735
},
"latency_us": {
"plain": {
"100": 20.5,
"500": 20.5,
"1000": 19.5
},
"aes256": {
"100": 20.5,
"500": 20.0,
"1000": 20.5
},
"aes128": {
"100": 21.0,
"500": 22.000000000000004,
"1000": 22.000000000000004
},
"chacha20": {
"100": 21.5,
"500": 23.000000000000004,
"1000": 25.5
}
}
}
}

View File

@ -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;
}
}

View File

@ -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,30 @@ 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 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"))?;
src[0] &= 0x0f; // restrict vlan id to 12 bits
dst[..2].copy_from_slice(&src[..2]);
if src[0..1] == [0, 0] {
// treat vlan id 0x000 as untagged
src.copy_within(2..8, 0);
dst.copy_within(2..8, 0);
return Ok((Address { data: src, len: 6 }, Address { data: dst, len: 6 }))
}
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);
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 +77,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 +177,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;
}
}

View File

@ -134,3 +134,36 @@ impl<TS: TimeSource> ClaimTable<TS> {
}
// 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::<MockTimeSource>::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::<MockTimeSource>::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;
}
}