tglock/src/bin/cli.rs

87 lines
3.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::sync::atomic::Ordering;
use clap::Parser;
use tg_unblock::{bypass, network, ws_proxy};
#[derive(Parser)]
#[command(name = "tg_unblock", version, about = "Обход блокировки Telegram через WebSocket-туннель")]
struct Args {
/// Порт SOCKS5-прокси
#[arg(short, long, default_value_t = 1080)]
port: u16,
/// Адрес привязки
#[arg(short, long, default_value = "127.0.0.1")]
bind: String,
/// Сменить DNS на Cloudflare 1.1.1.1 (нужен root/admin)
#[arg(long)]
dns: bool
}
fn main() {
let args = Args::parse();
let is_admin = bypass::check_admin();
let mut dns_was_set = false;
let mut adapter_name: Option<String> = None;
// DNS setup
if args.dns {
if !is_admin {
eprintln!("[!] Для смены DNS нужны права root/администратора");
} else {
adapter_name = network::detect_adapter();
if let Some(ref name) = adapter_name {
match bypass::set_dns(name, "1.1.1.1", "1.0.0.1") {
Ok(()) => {
bypass::flush_dns();
eprintln!("[+] DNS -> Cloudflare 1.1.1.1 (адаптер: {})", name);
dns_was_set = true;
}
Err(e) => eprintln!("[!] Не удалось сменить DNS: {}", e),
}
} else {
eprintln!("[!] Не удалось определить сетевой адаптер");
}
}
}
let stats = ws_proxy::ProxyStats::new();
stats.verbose.store(true, std::sync::atomic::Ordering::Relaxed);
let stats_signal = stats.clone();
eprintln!("[*] Запускаю SOCKS5-прокси на {}:{}...", args.bind, args.port);
eprintln!("[*] Подключение прокси в Telegram:");
eprintln!(" tg://socks?server={}&port={}", args.bind, args.port);
eprintln!("[*] Ctrl+C для остановки");
let rt = tokio::runtime::Runtime::new().expect("Не удалось создать tokio runtime");
rt.block_on(async {
// Graceful shutdown по Ctrl+C
let stats_ctrl = stats_signal.clone();
tokio::spawn(async move {
tokio::signal::ctrl_c().await.ok();
eprintln!("\n[*] Остановка...");
stats_ctrl.running.store(false, Ordering::SeqCst);
});
if let Err(e) = ws_proxy::run_proxy_bind(&args.bind, args.port, stats_signal).await {
eprintln!("[!] Прокси остановлен с ошибкой: {}", e);
}
});
// Cleanup DNS
if dns_was_set {
let name = adapter_name.or_else(network::detect_adapter);
if let Some(ref name) = name {
let _ = bypass::reset_dns(name);
bypass::flush_dns();
eprintln!("[+] DNS сброшен");
}
}
eprintln!("[*] Завершено. Всего соединений: {}", stats.total_conn.load(Ordering::Relaxed));
}