in dc/s2n-quic-dc/src/socket/bpf.rs [100:209]
fn routing_test() {
let mut options = Options::new("127.0.0.1:0".parse().unwrap());
options.blocking = true;
let Pair { writer, reader } = match Pair::open(options) {
Ok(pair) => pair,
Err(err)
if [
io::ErrorKind::PermissionDenied,
io::ErrorKind::AddrNotAvailable,
]
.contains(&err.kind()) =>
{
eprintln!("skipping test due to insufficient permissions");
return;
}
Err(err) => panic!("{err}"),
};
let timeout = Some(Duration::from_millis(100));
writer.set_read_timeout(timeout).unwrap();
reader.set_read_timeout(timeout).unwrap();
let addr = writer.local_addr().unwrap();
assert_eq!(addr, reader.local_addr().unwrap());
let mut reader_packets = Counts::default();
let mut writer_packets = Counts::default();
let sent_packets = AtomicUsize::new(0);
std::thread::scope(|s| {
s.spawn(|| {
let mut buffer = [0; 32];
while let Ok((_len, _src)) = reader.recv_from(&mut buffer) {
reader_packets.handle(buffer[0]);
}
});
s.spawn(|| {
let mut buffer = [0; 32];
while let Ok((_len, _src)) = writer.recv_from(&mut buffer) {
writer_packets.handle(buffer[0]);
}
});
for _ in 0..4 {
let client = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
// pace out senders to avoid drops on the receiver
std::thread::sleep(core::time::Duration::from_millis(1));
let sent_packets = &sent_packets;
s.spawn(move || {
for idx in 0u32..300 {
let mut packet = idx.to_le_bytes();
packet[0] = if idx % 2 == 0 {
// send a control packet
control::Tag::MAX
} else if idx / 2 % 2 == 0 {
// send a stream packet
stream::Tag::MAX
} else {
// send a garbage packet with the MSB set
control::Tag::MAX | 0b1000_0000
};
client.send_to(&packet, addr).unwrap();
sent_packets.fetch_add(1, Ordering::Relaxed);
// pace out packets to avoid drops on the receiver
if idx % 10 == 0 {
std::thread::sleep(core::time::Duration::from_millis(5));
}
}
dbg!();
});
}
});
dbg!(&reader_packets);
dbg!(&writer_packets);
// sometimes this test is a bit flaky in CI so we'll just log the failure for now
if reader_packets == Default::default() || writer_packets == Default::default() {
use std::io::{stderr, Write};
// we need to use stderr directly to bypass test harness capture
let _ = stderr()
.write_all(b"WARNING: no packets were received in cbpf test - skipping test\n");
return;
}
assert_eq!(writer_packets.stream, 0);
assert_eq!(writer_packets.garbage, 0);
assert_ne!(writer_packets.control, 0);
assert_ne!(reader_packets.stream, 0);
assert_ne!(reader_packets.garbage, 0);
assert_eq!(reader_packets.control, 0);
let reader_packets = reader_packets.total();
let writer_packets = writer_packets.total();
assert!(
reader_packets.abs_diff(writer_packets) < reader_packets.max(writer_packets) / 2,
"the difference should be less than half of the max received packets"
);
}