Skip to content

Commit fb22955

Browse files
authored
Optimization with reducing copies and eliminating buffer grows (#77)
* Optimized build and disable kanal async * adds packet store for optimized packet processing * adapt packet_store for optimized packet processing * Fix lint * refactor: replace Mutex with RwLock for latest packet storage * use THREAD_BUFFER in packet_store * add branches as dependency * fix ipv6 bug + adds unlikely branches * use PacketStore directly inside egress and ingress for much better performance than any channel * reuse string buffer instead of allocating new one each time * adds reusable display buffer for packets * optimize the packet_store even more (insomnia edition) * fix fmt * adds get and write_range_into optimized implementations * add cacheguard dependency and refactor PacketStore to use CacheGuard for atomic operations to improve cpu cache hits * optimize alert and synflood detection, add rustc-hash for FxHashmap * optimize alert packet counting * rollback link.rs change * gracefully handle out-of-bounds access in packet_store methods * add stack allocated ArrayVec optimization for packet_store * fix: correct packet_index handling in Inspection::render * clear alerts on next time frame * strict range of write_range_into for packet display buffer to avoid over copy when data is being written at realtime
1 parent 17a2577 commit fb22955

File tree

23 files changed

+758
-344
lines changed

23 files changed

+758
-344
lines changed

Cargo.lock

Lines changed: 46 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ homepage = "https://github.com/pythops/oryx"
1616
network-types = { git = "https://github.com/vadorovsky/network-types", rev = "b78424c" }
1717

1818
[profile.release]
19-
lto = "fat"
20-
strip = true
19+
opt-level = 3
20+
debug = false
21+
lto = 'fat'
22+
panic = 'abort'
2123
codegen-units = 1
24+
rpath = false

oryx-ebpf/Cargo.lock

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

oryx-ebpf/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ homepage = "https://github.com/pythops/oryx"
1111
aya-ebpf = "0.1.1"
1212
oryx-common = { path = "../oryx-common" }
1313
network-types = { git = "https://github.com/vadorovsky/network-types", rev = "b78424c" }
14+
branches = { version = "0.3", default-features = false }
1415

1516
[[bin]]
1617
name = "oryx"

oryx-ebpf/src/main.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use aya_ebpf::{
88
maps::{Array, HashMap, RingBuf},
99
programs::TcContext,
1010
};
11+
use branches::unlikely;
1112
use core::mem;
1213
use network_types::{
1314
arp::ArpHdr,
@@ -194,7 +195,7 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
194195
u16::from_be_bytes(unsafe { (*tcp_header).dest })
195196
};
196197

197-
if block_ipv4(addr, port) {
198+
if unlikely(block_ipv4(addr, port)) {
198199
return Ok(TC_ACT_SHOT); //block packet
199200
}
200201

@@ -227,7 +228,7 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
227228
u16::from_be_bytes(unsafe { (*udp_header).dst })
228229
};
229230

230-
if block_ipv4(addr, port) {
231+
if unlikely(block_ipv4(addr, port)) {
231232
return Ok(TC_ACT_SHOT); //block packet
232233
}
233234

@@ -260,7 +261,7 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
260261
u16::from_be_bytes(unsafe { (*sctp_header).dst })
261262
};
262263

263-
if block_ipv4(addr, port) {
264+
if unlikely(block_ipv4(addr, port)) {
264265
return Ok(TC_ACT_SHOT); //block packet
265266
}
266267

@@ -389,7 +390,7 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
389390
}
390391
}
391392
IpProto::Sctp => {
392-
let sctp_header: *const SctpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv4Hdr::LEN)?;
393+
let sctp_header: *const SctpHdr = ptr_at(&ctx, EthHdr::LEN + Ipv6Hdr::LEN)?;
393394

394395
let port = if is_ingress() {
395396
u16::from_be_bytes(unsafe { (*sctp_header).src })
@@ -401,7 +402,7 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
401402
return Ok(TC_ACT_SHOT); //block packet
402403
}
403404

404-
if filter_packet(Protocol::Network(NetworkProtocol::Ipv4))
405+
if filter_packet(Protocol::Network(NetworkProtocol::Ipv6))
405406
|| filter_packet(Protocol::Transport(TransportProtocol::SCTP))
406407
|| filter_direction()
407408
{

oryx-tui/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ oryx-common = { path = "../oryx-common" }
1919
mio = { version = "1", features = ["os-poll", "os-ext"] }
2020
itertools = "0.14"
2121
dirs = "6"
22-
kanal = "0.1"
22+
kanal = { version = "0.1", default-features = false }
2323
mimalloc = "0.1"
2424
clap = { version = "4", features = ["derive", "cargo"] }
2525
network-types = { workspace = true }
@@ -32,6 +32,10 @@ regex = "1"
3232
chrono = "0.4"
3333
strum = { version = "0.27", features = ["derive"] }
3434
anyhow = "1"
35+
branches = "0.3"
36+
cacheguard = "0.1"
37+
rustc-hash = "2.1.1"
38+
arrayvec = "0.7"
3539

3640
[[bin]]
3741
name = "oryx"

oryx-tui/src/app.rs

Lines changed: 6 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,16 @@
1-
use chrono::Utc;
21
use clap::ArgMatches;
32
use itertools::Itertools;
4-
use oryx_common::{
5-
RawData, RawFrame,
6-
protocols::{LinkProtocol, NetworkProtocol, TransportProtocol},
7-
};
3+
use oryx_common::protocols::{LinkProtocol, NetworkProtocol, TransportProtocol};
84
use ratatui::{
95
Frame,
106
layout::{Constraint, Direction, Layout},
117
};
12-
use std::{
13-
error,
14-
str::FromStr,
15-
sync::{Arc, RwLock},
16-
thread,
17-
time::Duration,
18-
};
8+
use std::{error, str::FromStr, thread, time::Duration};
199

2010
use crate::{
21-
filter::Filter,
22-
help::Help,
23-
packet::{EthFrame, direction::TrafficDirection},
11+
filter::Filter, filter::IoChannels, help::Help, notification::Notification,
12+
packet::direction::TrafficDirection, packet_store::PacketStore, section::Section,
2413
};
25-
use crate::{filter::IoChannels, notification::Notification};
26-
use crate::{packet::AppPacket, section::Section};
2714

2815
pub type AppResult<T> = std::result::Result<T, Box<dyn error::Error>>;
2916

@@ -40,7 +27,6 @@ pub enum ActivePopup {
4027

4128
#[derive(Debug)]
4229
pub struct DataEventHandler {
43-
pub sender: kanal::Sender<[u8; RawFrame::LEN]>,
4430
pub handler: thread::JoinHandle<()>,
4531
}
4632

@@ -50,46 +36,20 @@ pub struct App {
5036
pub help: Help,
5137
pub filter: Filter,
5238
pub start_sniffing: bool,
53-
pub app_packets: Arc<RwLock<Vec<AppPacket>>>,
39+
pub app_packets: PacketStore,
5440
pub notifications: Vec<Notification>,
5541
pub section: Section,
56-
pub data_channel_sender: kanal::Sender<([u8; RawData::LEN], TrafficDirection)>,
5742
pub is_editing: bool,
5843
pub active_popup: Option<ActivePopup>,
5944
pub start_from_cli: bool,
6045
}
6146

6247
impl App {
6348
pub fn new(cli_args: &ArgMatches) -> Self {
64-
let app_packets = Arc::new(RwLock::new(Vec::with_capacity(
65-
AppPacket::LEN * 1024 * 1024,
66-
)));
67-
68-
let (sender, receiver) = kanal::unbounded();
49+
let app_packets = PacketStore::new();
6950

7051
let firewall_channels = IoChannels::new();
7152

72-
thread::spawn({
73-
let app_packets = app_packets.clone();
74-
move || loop {
75-
if let Ok((raw_data, direction)) = receiver.recv() {
76-
let data = RawData::from(raw_data);
77-
let frame = EthFrame::from(data.frame);
78-
let pid = data.pid;
79-
80-
let mut app_packets = app_packets.write().unwrap();
81-
82-
let app_packet = AppPacket {
83-
frame,
84-
direction,
85-
pid,
86-
timestamp: Utc::now(),
87-
};
88-
app_packets.push(app_packet);
89-
}
90-
}
91-
});
92-
9353
let (interface_name, transport_protocols, network_protocols, link_protocols, direction) = {
9454
if let Some(interface) = cli_args.get_one::<String>("interface") {
9555
let transport_protocols = {
@@ -193,7 +153,6 @@ impl App {
193153
app_packets: app_packets.clone(),
194154
notifications: Vec::new(),
195155
section: Section::new(app_packets.clone(), firewall_channels.clone()),
196-
data_channel_sender: sender,
197156
is_editing: false,
198157
active_popup: None,
199158
start_from_cli: interface_name.is_some(),

oryx-tui/src/bandwidth.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ impl Bandwidth {
9595
}
9696

9797
loop {
98+
buffer.clear();
9899
thread::sleep(Duration::from_secs(1));
99100
if fd.seek(std::io::SeekFrom::Start(0)).is_err() {
100101
drop(fd);
101102
fd = File::open("/proc/net/dev").unwrap();
102103
}
103-
let mut buffer = String::new();
104104
fd.read_to_string(&mut buffer).unwrap();
105105

106106
let mut lines = buffer.lines();

0 commit comments

Comments
 (0)