summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock68
-rw-r--r--Cargo.toml1
-rw-r--r--src/platform/linux.rs68
3 files changed, 45 insertions, 92 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 50f3cc1..31feccf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -57,15 +57,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
[[package]]
-name = "block2"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
-dependencies = [
- "objc2",
-]
-
-[[package]]
name = "bumpalo"
version = "3.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -100,12 +91,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
-name = "cfg_aliases"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
-
-[[package]]
name = "ciborium"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -224,17 +209,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
-name = "ctrlc"
-version = "3.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162"
-dependencies = [
- "dispatch2",
- "nix 0.31.2",
- "windows-sys",
-]
-
-[[package]]
name = "daemonize"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -244,29 +218,16 @@ dependencies = [
]
[[package]]
-name = "dispatch2"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
-dependencies = [
- "bitflags",
- "block2",
- "libc",
- "objc2",
-]
-
-[[package]]
name = "dpibreak"
version = "0.6.1"
dependencies = [
"anyhow",
"criterion",
- "ctrlc",
"daemonize",
"etherparse 0.18.2",
"libc",
"nfq-updated",
- "nix 0.27.1",
+ "nix",
"socket2",
"windivert",
"windows-services",
@@ -374,18 +335,6 @@ dependencies = [
]
[[package]]
-name = "nix"
-version = "0.31.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
-dependencies = [
- "bitflags",
- "cfg-if",
- "cfg_aliases",
- "libc",
-]
-
-[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -395,21 +344,6 @@ dependencies = [
]
[[package]]
-name = "objc2"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f"
-dependencies = [
- "objc2-encode",
-]
-
-[[package]]
-name = "objc2-encode"
-version = "4.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
-
-[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index f982c3d..44a4542 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -39,7 +39,6 @@ socket2 = { version = "0.6", features = ["all"] }
nix = { version = "0.27.1", features = ["fs", "user"] }
daemonize = "0.5.0"
libc = "0.2"
-ctrlc = { version = "3.4", features = ["termination"] }
[target.'cfg(windows)'.dependencies]
windivert = { version = "0.6.0" }
diff --git a/src/platform/linux.rs b/src/platform/linux.rs
index c774d77..975c90c 100644
--- a/src/platform/linux.rs
+++ b/src/platform/linux.rs
@@ -1,9 +1,10 @@
// SPDX-FileCopyrightText: 2025-2026 Dilluti0n <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later
-use std::{os::fd::AsRawFd, sync::{
- LazyLock, atomic::{AtomicBool, Ordering}
-}};
+use std::{
+ os::fd::{AsRawFd, OwnedFd},
+ sync::{LazyLock, atomic::{AtomicBool, Ordering}}
+};
use std::fs::OpenOptions;
use std::process::{Command, Stdio};
use std::io::Write;
@@ -24,7 +25,6 @@ use crate::pkt;
pub static IS_U32_SUPPORTED: AtomicBool = AtomicBool::new(false);
pub static IS_NFT_NOT_SUPPORTED: AtomicBool = AtomicBool::new(false);
-static RUNNING: AtomicBool = AtomicBool::new(true);
const INJECT_MARK: u32 = 0xD001;
const PID_FILE: &str = "/run/dpibreak.pid"; // TODO: unmagic this
@@ -240,38 +240,58 @@ enum PollResult {
Interrupted,
}
-fn poll_once(q: &nfq::Queue, rx: Option<&rxring::RxRing>) -> Result<PollResult> {
+fn poll_once(sfd: &OwnedFd, q: &nfq::Queue, rx: Option<&rxring::RxRing>) -> Result<PollResult> {
use std::io::Error;
use std::os::fd::AsRawFd;
- let mut fds = [libc::pollfd { fd: -1, events: libc::POLLIN, revents: 0 }; 2];
+ let mut fds = [libc::pollfd { fd: -1, events: libc::POLLIN, revents: 0 }; 3];
- fds[0].fd = q.as_raw_fd();
- if let Some(rx) = rx { fds[1].fd = rx.as_raw_fd() };
+ fds[0].fd = sfd.as_raw_fd();
+ fds[1].fd = q.as_raw_fd();
+ if let Some(rx) = rx { fds[2].fd = rx.as_raw_fd() };
match unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as _, -1) } {
-1 => {
let e = Error::last_os_error();
- if e.raw_os_error() == Some(libc::EINTR) {
- return Ok(PollResult::Interrupted);
- }
+
+ // EINTR not happen here since we blocked SIGINT on open_signalfd()
Err(e.into())
},
- _ => Ok(PollResult::Ready {
- q: fds[0].revents & libc::POLLIN != 0,
+ _ => {
+ if fds[0].revents & libc::POLLIN != 0 {
+ return Ok(PollResult::Interrupted);
+ }
+ Ok(PollResult::Ready {
+ q: fds[1].revents & libc::POLLIN != 0,
- // false if rx is None (fd=-1, revents set to 0 by poll)
- rx: fds[1].revents & libc::POLLIN != 0
- })
+ // false if rx is None (fd=-1, revents set to 0 by poll)
+ rx: fds[2].revents & libc::POLLIN != 0
+ })
+ }
}
}
-fn trap_exit() -> Result<()> {
- ctrlc::set_handler(|| {
- RUNNING.store(false, Ordering::SeqCst);
- }).context("handler: ")?;
+/// open signalfd for SIGINT and SIGTERM
+fn open_signalfd() -> Result<OwnedFd> {
+ use libc::*;
+ use std::io::Error;
+ use std::os::fd::FromRawFd;
- Ok(())
+ // SAFETY: sigaddset fails only when signum is invalid
+ unsafe {
+ let mut mask: sigset_t = std::mem::zeroed();
+ sigemptyset(&mut mask);
+ sigaddset(&mut mask, SIGTERM);
+ sigaddset(&mut mask, SIGINT);
+
+ let ret = pthread_sigmask(SIG_BLOCK, &mask, core::ptr::null_mut());
+ if ret < 0 { return Err(Error::last_os_error().into()); }
+
+ let raw = signalfd(-1, &mask, 0);
+ if raw < 0 { return Err(Error::last_os_error().into()); }
+
+ Ok(OwnedFd::from_raw_fd(raw))
+ }
}
pub fn run() -> Result<()> {
@@ -280,16 +300,16 @@ pub fn run() -> Result<()> {
_ = cleanup_rules(); // In case the previous execution was not cleaned properly
install_rules()?;
- trap_exit()?;
+ let sfd = open_signalfd()?;
let mut q = open_nfqueue()?;
let mut rx = if opt::fake_autottl() { Some(open_rxring()?) } else { None };
let mut buf = Vec::<u8>::with_capacity(PACKET_SIZE_CAP);
crate::splash!("{}", super::MESSAGE_AT_RUN);
- while RUNNING.load(Ordering::SeqCst) {
- let (q_ready, rx_ready) = match poll_once(&q, rx.as_ref())? {
+ loop {
+ let (q_ready, rx_ready) = match poll_once(&sfd, &q, rx.as_ref())? {
PollResult::Ready { q, rx } => (q, rx),
PollResult::Interrupted => break,
};