mirror of
https://github.com/egor-white/zaprett.git
synced 2025-12-10 05:19:42 +05:00
20
rust/crates/zaprett/src/autostart.rs
Normal file
20
rust/crates/zaprett/src/autostart.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use tokio::fs::File;
|
||||
use tokio::fs;
|
||||
use crate::MODULE_PATH;
|
||||
|
||||
pub async fn set_autostart(autostart: bool) -> Result<(), anyhow::Error> {
|
||||
let autostart_path = MODULE_PATH.join("autostart");
|
||||
|
||||
if autostart {
|
||||
File::create(autostart_path).await?;
|
||||
} else {
|
||||
fs::remove_file(autostart_path).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_autostart() {
|
||||
let file = MODULE_PATH.join("autostart");
|
||||
println!("{}", file.exists());
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
pub mod commands;
|
||||
|
||||
use clap::Parser;
|
||||
use getset::Getters;
|
||||
use commands::Command;
|
||||
use getset::Getters;
|
||||
|
||||
#[derive(Parser, Getters)]
|
||||
#[command(version)]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::service::{restart_service, service_status, start_service, stop_service};
|
||||
use crate::{bin_version, get_autostart, module_version, set_autostart};
|
||||
use crate::{bin_version, module_version};
|
||||
use clap::Subcommand;
|
||||
use log::error;
|
||||
use crate::autostart::{get_autostart, set_autostart};
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Command {
|
||||
@@ -53,7 +54,7 @@ impl Command {
|
||||
);
|
||||
}
|
||||
Command::SetAutostart { autostart } => {
|
||||
if let Err(err) = set_autostart(autostart).await {
|
||||
if let Err(err) = set_autostart(*autostart).await {
|
||||
error!("Failed to set auto start: {err}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,58 +2,29 @@ use crate::{MODULE_PATH, merge_files};
|
||||
use getset::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ListType {
|
||||
#[default]
|
||||
Whitelist,
|
||||
Blacklist,
|
||||
}
|
||||
|
||||
impl Default for ListType {
|
||||
fn default() -> Self {
|
||||
Self::Whitelist
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Getters)]
|
||||
#[derive(Default, Serialize, Deserialize, Getters)]
|
||||
#[getset(get = "pub")]
|
||||
#[serde(default)]
|
||||
pub struct Config {
|
||||
#[serde(default)]
|
||||
active_lists: Vec<String>,
|
||||
#[serde(default)]
|
||||
active_ipsets: Vec<String>,
|
||||
#[serde(default)]
|
||||
active_exclude_lists: Vec<String>,
|
||||
#[serde(default)]
|
||||
active_exclude_ipsets: Vec<String>,
|
||||
#[serde(default)]
|
||||
list_type: ListType,
|
||||
#[serde(default)]
|
||||
strategy: String,
|
||||
#[serde(default)]
|
||||
app_list: String,
|
||||
#[serde(default)]
|
||||
whitelist: Vec<String>,
|
||||
#[serde(default)]
|
||||
blacklist: Vec<String>,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
active_lists: vec![],
|
||||
active_ipsets: vec![],
|
||||
active_exclude_lists: vec![],
|
||||
active_exclude_ipsets: vec![],
|
||||
list_type: Default::default(),
|
||||
strategy: String::new(),
|
||||
app_list: String::new(),
|
||||
whitelist: vec![],
|
||||
blacklist: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ListType {
|
||||
/// # Returns
|
||||
///
|
||||
|
||||
@@ -3,6 +3,7 @@ pub mod config;
|
||||
mod daemon;
|
||||
pub mod iptables_rust;
|
||||
mod service;
|
||||
mod autostart;
|
||||
|
||||
use ini::Ini;
|
||||
use libnfqws::nfqws_main;
|
||||
@@ -11,9 +12,8 @@ use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
use std::path::Path;
|
||||
use std::sync::LazyLock;
|
||||
use tokio::fs;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::{AsyncWriteExt, copy};
|
||||
use tokio::io::{copy, AsyncWriteExt};
|
||||
|
||||
pub static MODULE_PATH: LazyLock<&Path> = LazyLock::new(|| Path::new("/data/adb/modules/zaprett"));
|
||||
pub static ZAPRETT_DIR_PATH: LazyLock<&Path> =
|
||||
@@ -28,23 +28,6 @@ pub static DEFAULT_START: &str = "
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 $hostlist
|
||||
";
|
||||
|
||||
async fn set_autostart(autostart: &bool) -> Result<(), anyhow::Error> {
|
||||
let autostart_path = MODULE_PATH.join("autostart");
|
||||
|
||||
if *autostart {
|
||||
File::create(autostart_path).await?;
|
||||
} else {
|
||||
fs::remove_file(autostart_path).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_autostart() {
|
||||
let file = MODULE_PATH.join("autostart");
|
||||
println!("{}", file.exists());
|
||||
}
|
||||
|
||||
fn module_version() {
|
||||
if let Ok(prop) = Ini::load_from_file(MODULE_PATH.join("module.prop"))
|
||||
&& let Some(props) = prop.section::<String>(None)
|
||||
@@ -66,16 +49,16 @@ pub async fn merge_files(
|
||||
let mut output_file = File::create(output_path).await?;
|
||||
|
||||
for input in input_paths {
|
||||
let input_path = input.as_ref();
|
||||
let mut input_file = File::open(input_path)
|
||||
let input = input.as_ref();
|
||||
|
||||
let mut input_file = File::open(input)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to open {}: {}", input_path.display(), e))?;
|
||||
.map_err(|e| format!("Failed to open {}: {e}", input.display()))?;
|
||||
|
||||
copy(&mut input_file, &mut output_file).await.map_err(|e| {
|
||||
format!(
|
||||
"Failed to write contents of {}: {}",
|
||||
input_path.display(),
|
||||
e
|
||||
"Failed to write contents of {}: {e}",
|
||||
input.display()
|
||||
)
|
||||
})?;
|
||||
}
|
||||
@@ -96,6 +79,7 @@ fn run_nfqws(args_str: &str) -> anyhow::Result<()> {
|
||||
} else {
|
||||
args.extend(args_str.split_whitespace().map(String::from));
|
||||
}
|
||||
|
||||
let c_args: Vec<CString> = args
|
||||
.into_iter()
|
||||
.map(|arg| CString::new(arg).unwrap())
|
||||
|
||||
@@ -6,7 +6,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
pretty_env_logger::init();
|
||||
|
||||
let cli = CliApp::parse();
|
||||
match &cli.cmd() {
|
||||
match cli.cmd() {
|
||||
Some(cmd) => cmd.exec().await?,
|
||||
None => println!("zaprett installed. Join us: t.me/zaprett_module"),
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ use nix::sys::signal::{Signal, kill};
|
||||
use nix::unistd::{Pid, Uid};
|
||||
use regex::Regex;
|
||||
use std::borrow::Cow;
|
||||
use std::path::Path;
|
||||
use sysctl::Sysctl;
|
||||
use sysctl::{Ctl, CtlValue, Sysctl};
|
||||
use sysinfo::{Pid as SysPid, System};
|
||||
use tokio::fs;
|
||||
use tokio::fs::File;
|
||||
@@ -20,7 +19,7 @@ pub async fn start_service() -> anyhow::Result<()> {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
|
||||
if service_status().await.unwrap() {
|
||||
if service_status().await? {
|
||||
bail!("zaprett already started")
|
||||
}
|
||||
|
||||
@@ -62,8 +61,8 @@ pub async fn start_service() -> anyhow::Result<()> {
|
||||
.replace_all(&strat_modified, ZAPRETT_DIR_PATH.to_str().unwrap())
|
||||
.into_owned();
|
||||
|
||||
let ctl = sysctl::Ctl::new("net.netfilter.nf_conntrack_tcp_be_liberal")?;
|
||||
ctl.set_value(sysctl::CtlValue::String("1".into()))?;
|
||||
let ctl = Ctl::new("net.netfilter.nf_conntrack_tcp_be_liberal")?;
|
||||
ctl.set_value(CtlValue::String("1".into()))?;
|
||||
|
||||
setup_iptables_rules().expect("setup iptables rules");
|
||||
|
||||
@@ -77,8 +76,8 @@ pub async fn stop_service() -> anyhow::Result<()> {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
|
||||
if !service_status().await.unwrap() {
|
||||
bail!("zaprett service alreeady stopped")
|
||||
if !service_status().await? {
|
||||
bail!("zaprett service already stopped")
|
||||
}
|
||||
|
||||
clear_iptables_rules().expect("clear iptables rules");
|
||||
@@ -107,19 +106,17 @@ pub async fn service_status() -> anyhow::Result<bool> {
|
||||
bail!("Running not from root, exiting");
|
||||
};
|
||||
|
||||
let pid_i32 = match fs::read_to_string(Path::new(*MODULE_PATH).join("tmp/pid.lock")).await {
|
||||
Ok(s) => match s.trim().parse::<i32>() {
|
||||
Ok(pid) => pid,
|
||||
Err(_) => return Ok(false),
|
||||
},
|
||||
Err(_) => return Ok(false),
|
||||
let Ok(Some(pid)) = fs::read_to_string(MODULE_PATH.join("/tmp/pid.lock"))
|
||||
.await
|
||||
.map(|s| s.trim().parse::<usize>().ok())
|
||||
else {
|
||||
bail!("failed to get pid");
|
||||
};
|
||||
let pid = SysPid::from(pid_i32 as usize);
|
||||
let system = System::new_all();
|
||||
if let Some(process) = system.process(pid) {
|
||||
if process.name() == "zaprett" {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
|
||||
let is_zaprett = System::new_all()
|
||||
.process(SysPid::from(pid))
|
||||
.map(|process| process.name() == "zaprett")
|
||||
.unwrap_or(false);
|
||||
|
||||
Ok(is_zaprett)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user