15 个版本
使用旧的 Rust 2015
0.3.1 | 2020 年 6 月 2 日 |
---|---|
0.3.0 | 2018 年 6 月 20 日 |
0.2.7 | 2018 年 6 月 12 日 |
0.2.5 | 2018 年 5 月 31 日 |
0.1.1 | 2017 年 12 月 29 日 |
#660 在 Unix API 中
25KB
554 行
高性能的 Rust AF_PACKET 绑定
这个库旨在提供一个高效、安全且易用的方式,在多线程中读取接口上的原始数据包。其主要用途是网络安全和监控应用,结合类似 nom
(https://github.com/Geal/nom) 的 crate 来构建协议解码器和更复杂的分析引擎。
40 行代码的多线程原始接收器
Linux 内核提供基于散列元组的流平衡,因此线程不需要相互通信即可进行流重组。然而,这种行为是可以配置的。在 https://github.com/DominoTree/rs-dns-sniffer/blob/master/src/main.rs》可以看到一个约 70 行代码的全多线程 DNS 嗅探器。它在一台八核机器上每秒可以解码超过 120,000 条 DNS 消息而不会丢失任何帧,并且已经测试超过每秒 1,500,000 条记录。
extern crate af_packet;
extern crate num_cpus;
use std::env;
use std::thread;
fn main() {
//get args
let args: Vec<String> = env::args().collect();
//create a vec for file descriptors to poll for statistics
let mut fds = Vec::<i32>::new();
//spawn one thread per CPU
for _ in 0..num_cpus::get() {
let interface = args[1].clone();
//open an mmap()ed ring buffer for this thread
let mut ring = af_packet::Ring::from_if_name(&interface).unwrap();
//store the fd from the ring to get stats later
fds.push(ring.fd);
thread::spawn(move || {
//move struct into the thread
//receive blocks and process them
loop {
let mut block = ring.get_block();
for _packet in block.get_raw_packets() {
//process frame data here
}
block.mark_as_consumed();
}
});
}
//Below is to print statistics only
let mut packets: u64 = 0;
let mut drops: u64 = 0;
loop {
let mut stats: (u64, u64) = (0, 0);
for fd in &fds {
let ring_stats = af_packet::get_rx_statistics(*fd).unwrap();
stats.0 += ring_stats.tp_drops as u64;
stats.1 += ring_stats.tp_packets as u64;
}
drops += stats.0;
packets += stats.1;
eprintln!("{} frames received per second, {} dropped. {} total drops of {} total packets ({}%)", stats.1, stats.0, drops, packets, format!("{:.*}", 4, drops as f64 / packets as f64 * 100 as f64));
thread::sleep(std::time::Duration::from_secs(1));
}
}
基于 Tom Karpiniec (http://thomask.sdf.org/blog/2017/09/01/layer-2-raw-sockets-on-rustlinux.html) 和 Herman Radtke (http://hermanradtke.com/2016/03/17/unions-rust-ffi.html) 的工作
依赖项
~1MB
~16K SLoC