comments remove

This commit is contained in:
2026-03-20 15:05:22 +07:00
parent bc8662034f
commit ea3492c6a7
19 changed files with 43 additions and 149 deletions
+2 -4
View File
@@ -40,10 +40,10 @@ impl DnsHandler {
if needs_update {
let p_clone = self.cache_path.clone();
// Просто спавним асинхронную задачу
tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(10)).await;
// Теперь вызываем асинхронно через .await
if let Err(e) = Self::download_blocklist_async(p_clone).await {
netrunner_logger::error!("DNS: Background update failed: {}", e);
}
@@ -53,7 +53,6 @@ impl DnsHandler {
Ok(())
}
// Делаем функцию асинхронной и убираем block_on
async fn download_blocklist_async(cache_path: String) -> anyhow::Result<()> {
info!("DNS: Starting background download to {}", cache_path);
@@ -112,7 +111,6 @@ impl DnsHandler {
.set_recursion_available(true)
.add_query(query.clone());
// Проверка блокировок
if self.forbidden_suffixes.iter().any(|s| name.ends_with(s))
|| self.block_list.contains(&name)
{
+1 -1
View File
@@ -1,4 +1,4 @@
use crate::connections::dns::DnsHandler; // проверь путь
use crate::connections::dns::DnsHandler;
use crate::connections::ip_store::FakeIpStore;
use smoltcp::socket::udp;
-8
View File
@@ -14,18 +14,14 @@ use tokio_util::sync::CancellationToken;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. Инициализация логгера (теперь он внутри асинхронного контекста)
netrunner_logger::Logger::init();
info!("Initializing NetRunner Stack...");
// 2. Инициализация DNS асинхронно
// Передаем пустую строку или путь к кэшу (на десктопе можно ".")
let mut dns_handler = DnsHandler::new(".");
if let Err(e) = dns_handler.init().await {
error!("Failed to initialize DNS blocklist: {}", e);
}
// 3. Настройка TUN устройства
let tun_device = Tun::create(|config| {
config
.tun_name("netr0")
@@ -41,7 +37,6 @@ async fn main() -> anyhow::Result<()> {
info!("TUN interface is UP: 10.0.0.1/24");
// 4. Конфигурация стека протоколов (MTU 1280 для стабильности)
let config = Config::new(smoltcp::wire::HardwareAddress::Ip);
let mut caps = DeviceCapabilities::default();
caps.max_transmission_unit = 1280;
@@ -56,7 +51,6 @@ async fn main() -> anyhow::Result<()> {
let proxy_ip = network.get_self_local_address();
// 5. Запуск сетевого прокси в отдельной задаче
let network_token = CancellationToken::new();
let net_token_for_spawn = network_token.clone();
tokio::spawn(async move {
@@ -64,7 +58,6 @@ async fn main() -> anyhow::Result<()> {
network.run(net_token_for_spawn).await;
});
// 6. Инициализация Engine
let mut engine = Engine::new(config, caps, proxy_ip, dns_handler);
engine.set_any_ip(true);
engine.set_transparent_mode();
@@ -84,7 +77,6 @@ async fn main() -> anyhow::Result<()> {
}
}
// 8. Очистка ресурсов
network_token.cancel();
info!("Restoring system routing...");
let addr: std::net::SocketAddr = remote_address.parse().expect("Invalid address format");
+5 -6
View File
@@ -43,8 +43,7 @@ impl SessionManager {
pub(crate) fn spawn_session(
&self,
remote_address: String,
#[cfg(any(target_os = "android", target_os = "ios"))] // Путь обязателен для мобилок
tun_fd: Option<i32>,
#[cfg(any(target_os = "android", target_os = "ios"))] tun_fd: Option<i32>,
#[cfg(any(target_os = "android", target_os = "ios"))] cache_dir: String,
) -> Arc<Session> {
let runtime = get_runtime();
@@ -62,11 +61,11 @@ impl SessionManager {
#[cfg(any(target_os = "android", target_os = "ios"))]
{
cache_dir
} // Используем путь из мобильного приложения
}
#[cfg(any(target_os = "linux", target_os = "windows"))]
{
".".to_string()
} // На ПК пишем в локальную папку
}
};
let mut dns_handler = DnsHandler::new(&cache_path);
@@ -132,9 +131,9 @@ impl SessionManager {
info!("Engine async task started");
tokio::select! {
// Добавляем обработку результата прямо здесь
res = engine.run(tun_device) => {
// Теперь эта ветка возвращает (), так как мы обработали результат
info!("Engine loop finished: {:?}", res);
},
_ = cancel_token_for_engine.cancelled() => {
+4 -12
View File
@@ -114,22 +114,18 @@ impl ConnectionManager {
fn handle_tcp(&mut self, handle: SocketHandle, socket: &mut tcp::Socket) {
use tcp::State;
// 1. Очистка закрытых сокетов
if socket.state() == State::Closed {
// Если сокет закрыт, удаляем его сессию и помечаем на удаление из сета
if self.active_tcp_sessions.contains_key(&handle) {
debug!(%handle, "TCP session closed, removing from active sessions");
self.active_tcp_sessions.remove(&handle);
}
// Добавляем в очередь на удаление из SocketSet (чтобы освободить память)
if !self.sockets_to_remove.contains(&handle) {
self.sockets_to_remove.push(handle);
}
return;
}
// 2. Инициализация сессии при установке соединения
if socket.state() == State::Established && !self.active_tcp_sessions.contains_key(&handle) {
let target = self.resolve_target(socket);
@@ -145,12 +141,10 @@ impl ConnectionManager {
self.active_tcp_sessions.insert(handle, conn);
}
// 3. Тик активной сессии (проброс данных в прокси)
if let Some(conn) = self.active_tcp_sessions.get_mut(&handle) {
if !conn.tick(socket) {
debug!(%handle, "Connection tick failed, aborting.");
socket.abort();
// Сессия удалится на следующем проходе, когда стейт станет Closed
}
}
@@ -190,9 +184,9 @@ impl ConnectionManager {
fn create_dynamic_tcp_socket<'a>(port: u16) -> tcp::Socket<'a> {
let buf_size = match port {
443 | 80 => 256 * 1024, // 256 KB для веба
22 | 53 | 123 => 16 * 1024, // 16 KB для мелких протоколов (SSH, DNS over TCP, NTP)
_ => 64 * 1024, // Дефолт
443 | 80 => 256 * 1024,
22 | 53 | 123 => 16 * 1024,
_ => 64 * 1024,
};
let mut socket = tcp::Socket::new(
@@ -200,7 +194,7 @@ impl ConnectionManager {
tcp::SocketBuffer::new(vec![0; buf_size]),
);
socket.set_nagle_enabled(false); // Для отзывчивости (особенно в играх типа Silent Hill, если через VPN)
socket.set_nagle_enabled(false);
socket.set_ack_delay(None);
socket
}
@@ -216,12 +210,10 @@ impl ConnectionManager {
return;
};
// Ищем только SYN (начало соединения)
if tcp_packet.syn() && !tcp_packet.ack() {
let dst_port = tcp_packet.dst_port();
let dst_addr = ip_packet.dst_addr();
// Проверяем, не создали ли мы уже такой сокет на предыдущем шаге
if !self.has_active_session(socket_set, dst_addr.into(), dst_port) {
debug!(target: "netrunner", "Dynamic TCP: Creating socket for {}:{}", dst_addr, dst_port);
+4 -6
View File
@@ -15,7 +15,6 @@ use smoltcp::{
};
use tokio::sync::mpsc;
// --- TokenBuffer (без изменений, он у тебя отличный) ---
const TOKEN_BUFFER_LIST_MAX_SIZE: usize = 64;
static TOKEN_BUFFER_LIST: LazyLock<Mutex<Vec<BytesMut>>> = LazyLock::new(|| Mutex::new(Vec::new()));
@@ -61,11 +60,10 @@ impl DerefMut for TokenBuffer {
}
}
// --- VirtTunDevice ---
pub struct VirtTunDevice {
capabilities: DeviceCapabilities,
rx_queue: mpsc::UnboundedReceiver<TokenBuffer>, // smoltcp читает отсюда
tx_queue: mpsc::UnboundedSender<TokenBuffer>, // smoltcp пишет сюда
rx_queue: mpsc::UnboundedReceiver<TokenBuffer>,
tx_queue: mpsc::UnboundedSender<TokenBuffer>,
rx_avail: Arc<AtomicBool>,
}
@@ -74,8 +72,8 @@ impl VirtTunDevice {
capabilities: DeviceCapabilities,
) -> (
Self,
mpsc::UnboundedSender<TokenBuffer>, // Канал, чтобы закидывать пакеты в smoltcp
mpsc::UnboundedReceiver<TokenBuffer>, // Канал, чтобы забирать готовые пакеты из smoltcp
mpsc::UnboundedSender<TokenBuffer>,
mpsc::UnboundedReceiver<TokenBuffer>,
Arc<AtomicBool>,
) {
let (to_smoltcp_tx, to_smoltcp_rx) = mpsc::unbounded_channel();
+1 -13
View File
@@ -29,11 +29,7 @@ pub struct Engine {
socket_set: SocketSet<'static>,
manager: ConnectionManager,
device: VirtTunDevice,
// Канал для инъекции пакетов в smoltcp
to_smoltcp_tx: UnboundedSender<TokenBuffer>,
// Временное хранилище канала выхода из smoltcp (отдадим воркеру в run)
from_smoltcp_rx: Option<UnboundedReceiver<TokenBuffer>>,
avail: Arc<AtomicBool>,
@@ -47,7 +43,7 @@ impl Engine {
dns_handler: DnsHandler,
) -> Self {
let now = Engine::current_time();
// Смотри, как чисто мы получаем компоненты:
let (mut device, to_smoltcp_tx, from_smoltcp_rx, avail) = VirtTunDevice::new(caps);
let interface = Interface::new(config, &mut device, now);
@@ -69,25 +65,19 @@ impl Engine {
info!("Current routes: {:?}", self.interface.routes());
let (writer, reader) = tun.split().expect("Failed to split TUN");
// 1. Создаем трубу для ВХОДЯЩЕГО трафика: TUN -> Engine
let (tun_to_engine_tx, mut tun_to_engine_rx) = mpsc::unbounded_channel();
Self::spawn_tun_reader(reader, tun_to_engine_tx, self.avail.clone());
// 2. Запускаем трубу ИСХОДЯЩЕГО трафика: smoltcp -> TUN
let from_smoltcp_rx = self.from_smoltcp_rx.take().expect("Engine started twice");
Self::spawn_tun_writer(writer, from_smoltcp_rx);
let mut last_log = StdInstant::now();
// 3. Главный цикл (ДИСПЕТЧЕР)
loop {
// Читаем всё, что прилетело из операционной системы
while let Ok(token) = tun_to_engine_rx.try_recv() {
// АНАЛИЗ: Создаем сокет, если это новый SYN
self.manager
.try_create_socket_from_packet(&token, &mut self.socket_set);
// ПЕРЕДАЧА: Закидываем пакет в виртуальную сетевую карту smoltcp
if self.to_smoltcp_tx.send(token).is_ok() {
self.device.mark_rx_available();
}
@@ -131,7 +121,6 @@ impl Engine {
sleep(sleep_duration).await;
}
// Воркер: Читает ОС -> Шлет в Engine
fn spawn_tun_reader(
mut reader: DeviceReader,
to_engine: UnboundedSender<TokenBuffer>,
@@ -173,7 +162,6 @@ impl Engine {
});
}
// Воркер: Читает smoltcp -> Шлет в ОС
fn spawn_tun_writer(
mut writer: DeviceWriter,
mut from_smoltcp: UnboundedReceiver<TokenBuffer>,
+2 -14
View File
@@ -46,7 +46,7 @@ fn get_default_gateway() -> Option<String> {
.output()
.ok()?;
let stdout = String::from_utf8_lossy(&output.stdout);
// Простой парсинг: ищем строку с 0.0.0.0 и берем IP из колонки шлюза
stdout
.lines()
.find(|line| line.contains("0.0.0.0"))
@@ -59,19 +59,15 @@ pub fn setup_platform_routing(remote_address: &str) -> io::Result<()> {
#[cfg(target_os = "linux")]
{
// 1. Ядро
let _ = run_cmd_ext("sysctl -w net.ipv4.conf.all.rp_filter=0", true);
let _ = run_cmd_ext("sysctl -w net.ipv4.conf.netr0.rp_filter=0", true);
let _ = run_cmd_ext("sysctl -w net.ipv4.ip_forward=1", true);
// 2. Маршрутизация
let _ = run_cmd_ext("ip rule add fwmark 0x1 table 100", true);
let _ = run_cmd_ext("ip route add default dev netr0 table 100", true);
// 3. NFTables (Чиним ошибку удаления и синтаксис)
// Добавляем таблицу (если есть — ничего не сделает, если нет — создаст)
run_cmd_ext("nft add table ip netrunner", true)?;
// Очищаем таблицу перед работой, чтобы не плодить дубликаты
run_cmd_ext("nft flush table ip netrunner", true)?;
run_cmd_ext(
@@ -95,7 +91,6 @@ pub fn setup_platform_routing(remote_address: &str) -> io::Result<()> {
);
run_cmd_ext(&dns_redir, false)?;
// 4. DNS (resolvectl не знает 'metric', используем стандартный синтаксис)
let _ = run_cmd_ext("resolvectl dns netr0 10.0.0.2", true);
let _ = run_cmd_ext("resolvectl domain netr0 ~.", true);
@@ -106,17 +101,14 @@ pub fn setup_platform_routing(remote_address: &str) -> io::Result<()> {
{
let gateway = get_default_gateway().unwrap_or_else(|| "192.168.1.1".to_string());
// 1. Устанавливаем IP для адаптера
let _ = run_cmd_ext(
"netsh interface ipv4 set address name=\"netr0\" static 10.0.0.1 255.255.255.0 none",
true,
);
// 2. Ждем и получаем индекс именно нашего туннеля
let tun_idx = get_adapter_index("netr0")
.ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "Interface netr0 not found"))?;
// 3. Маршрут-исключение для прокси через физический шлюз
let _ = run_cmd_ext(
&format!(
"route add {} mask 255.255.255.255 {} metric 1",
@@ -125,7 +117,6 @@ pub fn setup_platform_routing(remote_address: &str) -> io::Result<()> {
true,
);
// 4. Глобальные маршруты через TUN (теперь с правильным if_idx)
run_cmd_ext(
&format!(
"route add 0.0.0.0 mask 128.0.0.0 10.0.0.2 if {} metric 5",
@@ -141,7 +132,6 @@ pub fn setup_platform_routing(remote_address: &str) -> io::Result<()> {
true,
)?;
// 5. DNS
let _ = run_cmd_ext(
"netsh interface ipv4 set dnsservers name=\"netr0\" static 10.0.0.2 primary",
true,
@@ -172,7 +162,6 @@ pub fn reset_platform_routing(proxy_ip: Option<&str>) -> io::Result<()> {
#[cfg(target_os = "windows")]
{
// Очищаем глобальные маршруты, иначе интернет не вернется
let _ = run_cmd_ext("route delete 0.0.0.0 mask 128.0.0.0", true);
let _ = run_cmd_ext("route delete 128.0.0.0 mask 128.0.0.0", true);
@@ -180,7 +169,6 @@ pub fn reset_platform_routing(proxy_ip: Option<&str>) -> io::Result<()> {
let _ = run_cmd_ext(&format!("route delete {}", ip), true);
}
// Сбрасываем DNS на автоматический (или удаляем наш)
let _ = run_cmd_ext(
"netsh interface ipv4 set dnsservers name=\"netr0\" source=dhcp",
true,