Skip to content

Commit b90cad5

Browse files
committed
refresh pid map
1 parent d1da41b commit b90cad5

File tree

23 files changed

+181
-1293
lines changed

23 files changed

+181
-1293
lines changed

oryx-ebpf/src/main.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33

44
use aya_ebpf::{
55
bindings::{TC_ACT_PIPE, TC_ACT_SHOT},
6-
macros::{classifier, map},
6+
macros::{cgroup_sock_addr, classifier, map},
77
maps::{Array, HashMap, RingBuf},
8-
programs::TcContext,
8+
programs::{SockAddrContext, TcContext},
9+
EbpfContext,
910
};
1011
use core::mem;
1112
use network_types::{
@@ -24,6 +25,9 @@ use oryx_common::{
2425
#[map]
2526
static DATA: RingBuf = RingBuf::with_byte_size(4096 * RawPacket::LEN as u32, 0);
2627

28+
#[map]
29+
static PID_DATA: RingBuf = RingBuf::with_byte_size(1024, 0);
30+
2731
#[map]
2832
static NETWORK_FILTERS: Array<u32> = Array::with_max_entries(8, 0);
2933

@@ -306,6 +310,24 @@ fn process(ctx: TcContext) -> Result<i32, ()> {
306310
Ok(TC_ACT_PIPE)
307311
}
308312

313+
#[cgroup_sock_addr(connect4)]
314+
pub fn socket_connect(ctx: SockAddrContext) -> i32 {
315+
match sock_connect(ctx) {
316+
Ok(ret) => ret,
317+
Err(ret) => ret,
318+
}
319+
}
320+
321+
fn sock_connect(ctx: SockAddrContext) -> Result<i32, i32> {
322+
let pid = ctx.pid();
323+
324+
if let Some(mut buf) = PID_DATA.reserve::<u32>(0) {
325+
unsafe { (*buf.as_mut_ptr()) = pid };
326+
buf.submit(0);
327+
}
328+
Ok(1)
329+
}
330+
309331
#[panic_handler]
310332
fn panic(_info: &core::panic::PanicInfo) -> ! {
311333
unsafe { core::hint::unreachable_unchecked() }

oryx-tui/src/app.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ratatui::{
55
};
66
use std::{
77
error,
8-
sync::{Arc, Mutex},
8+
sync::{atomic::AtomicBool, Arc, Mutex},
99
thread,
1010
time::Duration,
1111
};
@@ -14,7 +14,7 @@ use crate::{
1414
filter::Filter,
1515
help::Help,
1616
packet::{direction::TrafficDirection, NetworkPacket},
17-
pid,
17+
pid::{self, ConnectionMap},
1818
};
1919

2020
use crate::{filter::IoChannels, notification::Notification};
@@ -50,6 +50,8 @@ pub struct App {
5050
pub data_channel_sender: kanal::Sender<([u8; RawPacket::LEN], TrafficDirection)>,
5151
pub is_editing: bool,
5252
pub active_popup: Option<ActivePopup>,
53+
pub pid_terminate: Arc<AtomicBool>,
54+
pub pid_map: Arc<Mutex<ConnectionMap>>,
5355
}
5456

5557
impl Default for App {
@@ -61,19 +63,24 @@ impl Default for App {
6163
impl App {
6264
pub fn new() -> Self {
6365
let packets = Arc::new(Mutex::new(Vec::with_capacity(RawPacket::LEN * 1024 * 1024)));
66+
let pid_map = Arc::new(Mutex::new(ConnectionMap::new()));
6467

6568
let (sender, receiver) = kanal::unbounded();
6669

6770
let firewall_channels = IoChannels::new();
6871
thread::spawn({
6972
let packets = packets.clone();
73+
let pid_map = pid_map.clone();
7074
move || loop {
71-
let pid_map = pid::ConnectionMap::new();
7275
if let Ok((raw_packet, direction)) = receiver.recv() {
7376
let network_packet = NetworkPacket::from(raw_packet);
7477

7578
let pid = {
7679
if direction == TrafficDirection::Egress {
80+
let pid_map = {
81+
let map = pid_map.lock().unwrap();
82+
map.clone()
83+
};
7784
pid::get_pid(network_packet, &pid_map)
7885
} else {
7986
None
@@ -107,6 +114,8 @@ impl App {
107114
data_channel_sender: sender,
108115
is_editing: false,
109116
active_popup: None,
117+
pid_terminate: Arc::new(AtomicBool::new(false)),
118+
pid_map,
110119
}
111120
}
112121

@@ -147,6 +156,8 @@ impl App {
147156

148157
pub fn quit(&mut self) {
149158
self.filter.terminate();
159+
self.pid_terminate
160+
.store(true, std::sync::atomic::Ordering::Relaxed);
150161
thread::sleep(Duration::from_millis(110));
151162
self.running = false;
152163
}

oryx-tui/src/ebpf.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod egress;
22
mod firewall;
33
pub mod ingress;
4+
pub mod pid;
45

56
use std::{io, os::fd::AsRawFd};
67

@@ -16,8 +17,8 @@ pub struct RingBuffer<'a> {
1617
}
1718

1819
impl<'a> RingBuffer<'a> {
19-
fn new(ebpf: &'a mut Ebpf) -> Self {
20-
let buffer = RingBuf::try_from(ebpf.map_mut("DATA").unwrap()).unwrap();
20+
fn new(ebpf: &'a mut Ebpf, name: &'a str) -> Self {
21+
let buffer = RingBuf::try_from(ebpf.map_mut(name).unwrap()).unwrap();
2122
Self { buffer }
2223
}
2324

oryx-tui/src/ebpf/egress.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ pub fn load_egress(
193193
});
194194

195195
// packets reading
196-
let mut ring_buf = RingBuffer::new(&mut bpf);
196+
let mut ring_buf = RingBuffer::new(&mut bpf, "DATA");
197197

198198
poll.registry()
199199
.register(

oryx-tui/src/ebpf/ingress.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ pub fn load_ingress(
197197
});
198198

199199
// packets reader
200-
let mut ring_buf = RingBuffer::new(&mut bpf);
200+
let mut ring_buf = RingBuffer::new(&mut bpf, "DATA");
201201

202202
poll.registry()
203203
.register(

oryx-tui/src/ebpf/pid.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
use std::{
2+
fs::{self, File},
3+
os::fd::AsRawFd,
4+
sync::{atomic::AtomicBool, Arc, Mutex},
5+
thread,
6+
time::Duration,
7+
};
8+
9+
use aya::{
10+
include_bytes_aligned,
11+
programs::{CgroupAttachMode, CgroupSockAddr},
12+
EbpfLoader,
13+
};
14+
use log::error;
15+
16+
use crate::{
17+
event::Event,
18+
notification::{Notification, NotificationLevel},
19+
pid::ConnectionMap,
20+
};
21+
use mio::{unix::SourceFd, Events, Interest, Poll, Token};
22+
23+
use super::RingBuffer;
24+
25+
pub fn load_pid(
26+
pid_map: Arc<Mutex<ConnectionMap>>,
27+
notification_sender: kanal::Sender<Event>,
28+
terminate: Arc<AtomicBool>,
29+
) {
30+
thread::spawn({
31+
move || {
32+
let rlim = libc::rlimit {
33+
rlim_cur: libc::RLIM_INFINITY,
34+
rlim_max: libc::RLIM_INFINITY,
35+
};
36+
37+
unsafe { libc::setrlimit(libc::RLIMIT_MEMLOCK, &rlim) };
38+
39+
#[cfg(debug_assertions)]
40+
let mut bpf = match EbpfLoader::new().load(include_bytes_aligned!(
41+
"../../../target/bpfel-unknown-none/debug/oryx"
42+
)) {
43+
Ok(v) => v,
44+
Err(e) => {
45+
error!("Failed to load the pid eBPF bytecode. {}", e);
46+
Notification::send(
47+
"Failed to load the pid eBPF bytecode",
48+
NotificationLevel::Error,
49+
notification_sender,
50+
)
51+
.unwrap();
52+
return;
53+
}
54+
};
55+
56+
#[cfg(not(debug_assertions))]
57+
let mut bpf = match EbpfLoader::new().load(include_bytes_aligned!(
58+
"../../../target/bpfel-unknown-none/debug/oryx"
59+
)) {
60+
Ok(v) => v,
61+
Err(e) => {
62+
error!("Failed to load the pid eBPF bytecode. {}", e);
63+
Notification::send(
64+
"Failed to load the pid eBPF bytecode",
65+
NotificationLevel::Error,
66+
notification_sender,
67+
)
68+
.unwrap();
69+
return;
70+
}
71+
};
72+
73+
let sock_connect: &mut CgroupSockAddr = bpf
74+
.program_mut("socket_connect")
75+
.unwrap()
76+
.try_into()
77+
.unwrap();
78+
sock_connect.load().unwrap();
79+
let file = File::open("/sys/fs/cgroup/user.slice").unwrap();
80+
81+
sock_connect.attach(file, CgroupAttachMode::Single).unwrap();
82+
83+
let mut poll = Poll::new().unwrap();
84+
let mut events = Events::with_capacity(128);
85+
86+
let mut ring_buf = RingBuffer::new(&mut bpf, "PID_DATA");
87+
88+
poll.registry()
89+
.register(
90+
&mut SourceFd(&ring_buf.buffer.as_raw_fd()),
91+
Token(0),
92+
Interest::READABLE,
93+
)
94+
.unwrap();
95+
96+
loop {
97+
poll.poll(&mut events, Some(Duration::from_millis(100)))
98+
.unwrap();
99+
if terminate.load(std::sync::atomic::Ordering::Relaxed) {
100+
break;
101+
}
102+
for event in &events {
103+
if terminate.load(std::sync::atomic::Ordering::Relaxed) {
104+
break;
105+
}
106+
if event.token() == Token(0) && event.is_readable() {
107+
if terminate.load(std::sync::atomic::Ordering::Relaxed) {
108+
break;
109+
}
110+
while let Some(item) = ring_buf.next() {
111+
if terminate.load(std::sync::atomic::Ordering::Relaxed) {
112+
break;
113+
}
114+
let pid: [u8; 4] = item.to_owned().try_into().unwrap();
115+
let pid = u32::from_ne_bytes(pid);
116+
117+
let fd_dir = format!("/proc/{}/fd", pid);
118+
if let Ok(_fds) = fs::read_dir(&fd_dir) {
119+
let mut map = pid_map.lock().unwrap();
120+
*map = ConnectionMap::new();
121+
}
122+
}
123+
}
124+
}
125+
}
126+
127+
let _ = poll
128+
.registry()
129+
.deregister(&mut SourceFd(&ring_buf.buffer.as_raw_fd()));
130+
}
131+
});
132+
}

oryx-tui/src/handler.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::{
55

66
use crate::{
77
app::{ActivePopup, App, AppResult},
8+
ebpf::pid::load_pid,
89
event::Event,
910
filter::FocusedBlock,
1011
section::{stats::Stats, FocusedSection},
@@ -24,6 +25,11 @@ pub fn handle_key_events(
2425
app.section.stats = Some(Stats::new(app.packets.clone()));
2526
app.filter
2627
.start(event_sender.clone(), app.data_channel_sender.clone())?;
28+
load_pid(
29+
app.pid_map.clone(),
30+
event_sender.clone(),
31+
app.pid_terminate.clone(),
32+
);
2733

2834
sleep(Duration::from_millis(100));
2935
app.start_sniffing = true;

test-sock-addr/.gitignore

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)