generate update 2
This commit is contained in:
+28
-18
@@ -3,16 +3,18 @@ pub mod connections;
|
||||
pub mod tun;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use netrunner_core::proxy::{connection::connection::ConnectionRole, network::Network};
|
||||
use netrunner_core::{
|
||||
logger_init,
|
||||
proxy::{connection::connection::ConnectionRole, network::Network},
|
||||
};
|
||||
use smoltcp::{iface::Config, phy::DeviceCapabilities};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::OnceLock;
|
||||
use tokio::runtime::Runtime;
|
||||
use tokio::sync::oneshot;
|
||||
use tracing::info;
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::tun::{engine::Engine, tun::Tun};
|
||||
|
||||
static RUNTIME: OnceLock<Runtime> = OnceLock::new();
|
||||
|
||||
fn get_runtime() -> &'static Runtime {
|
||||
@@ -23,7 +25,7 @@ fn get_runtime() -> &'static Runtime {
|
||||
.expect("Failed to create tokio runtime")
|
||||
})
|
||||
}
|
||||
// --- Обертка для Session ---
|
||||
|
||||
#[derive(uniffi::Object)]
|
||||
pub struct Session {
|
||||
shutdown_tx: Mutex<Option<oneshot::Sender<()>>>,
|
||||
@@ -43,20 +45,20 @@ impl Session {
|
||||
#[derive(uniffi::Object)]
|
||||
pub struct SessionManager;
|
||||
|
||||
#[uniffi::constructor]
|
||||
impl SessionManager {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[uniffi::export]
|
||||
impl SessionManager {
|
||||
#[uniffi::constructor]
|
||||
pub fn new() -> Self {
|
||||
logger_init();
|
||||
info!("SessionManager initialized");
|
||||
Self
|
||||
}
|
||||
|
||||
pub fn start(&self, remote_address: String, tun_fd: Option<i32>) -> Arc<Session> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let runtime = get_runtime();
|
||||
runtime.spawn(async move {
|
||||
info!("Starting VPN session...");
|
||||
info!("Starting VPN session thread...");
|
||||
|
||||
let tun_device = if let Some(fd) = tun_fd {
|
||||
info!("Using provided FD for TUN: {}", fd);
|
||||
@@ -73,8 +75,12 @@ impl SessionManager {
|
||||
.expect("Failed to init TUN")
|
||||
};
|
||||
|
||||
tun_device.setup_routing();
|
||||
tun_device.setup_dns_redirection();
|
||||
#[cfg(feature = "desktop")]
|
||||
{
|
||||
let proxy_ip = remote_address.split(':').next().unwrap_or(&remote_address);
|
||||
tun_device.setup_routing(proxy_ip).expect("Routing failed");
|
||||
tun_device.setup_dns_redirection().expect("DNS failed");
|
||||
}
|
||||
|
||||
// 2. Инициализация сети
|
||||
let config = Config::new(smoltcp::wire::HardwareAddress::Ip);
|
||||
@@ -82,6 +88,7 @@ impl SessionManager {
|
||||
caps.max_transmission_unit = 1500;
|
||||
caps.medium = smoltcp::phy::Medium::Ip;
|
||||
|
||||
info!("Initializing Network with remote: {}", remote_address);
|
||||
let network = Network::new(
|
||||
"0.0.0.0".into(),
|
||||
8080,
|
||||
@@ -90,12 +97,13 @@ impl SessionManager {
|
||||
);
|
||||
|
||||
let proxy_ip = network.get_self_local_address();
|
||||
|
||||
info!("Proxy self address: {:?}", proxy_ip);
|
||||
// Запускаем сетевой поток
|
||||
let net_handle = tokio::spawn(async move {
|
||||
network.run().await;
|
||||
});
|
||||
|
||||
info!("Configuring Engine...");
|
||||
// 3. Инициализация Engine
|
||||
let mut engine = Engine::new(config, caps, proxy_ip);
|
||||
engine.set_any_ip(true);
|
||||
@@ -103,10 +111,12 @@ impl SessionManager {
|
||||
engine.set_default_gateway(Ipv4Addr::new(10, 0, 0, 2));
|
||||
engine.activate();
|
||||
|
||||
info!("Engine activated");
|
||||
|
||||
// 4. Главный цикл с поддержкой остановки
|
||||
tokio::select! {
|
||||
_ = engine.run(tun_device) => {
|
||||
info!("Engine loop finished naturally.");
|
||||
res = engine.run(tun_device) => {
|
||||
error!("Engine loop terminated unexpectedly: {:?}", res);
|
||||
}
|
||||
_ = rx => {
|
||||
info!("Shutdown signal received. Cleaning up...");
|
||||
@@ -114,7 +124,7 @@ impl SessionManager {
|
||||
}
|
||||
|
||||
net_handle.abort();
|
||||
info!("VPN session stopped.");
|
||||
info!("VPN session fully stopped.");
|
||||
});
|
||||
|
||||
Arc::new(Session {
|
||||
|
||||
+3
-3
@@ -22,8 +22,8 @@ async fn main() {
|
||||
.up();
|
||||
})
|
||||
.expect("Failed to initialize TUN device");
|
||||
|
||||
tun_device.setup_routing();
|
||||
let remote_address: String = "62.60.244.156:443".into();
|
||||
tun_device.setup_routing(&remote_address);
|
||||
tun_device.setup_dns_redirection();
|
||||
|
||||
info!("TUN interface is UP: 10.0.0.1/24");
|
||||
@@ -31,7 +31,7 @@ async fn main() {
|
||||
let config = Config::new(smoltcp::wire::HardwareAddress::Ip);
|
||||
|
||||
let mut caps = DeviceCapabilities::default();
|
||||
let remote_address: String = "62.60.244.156:443".into();
|
||||
|
||||
caps.max_transmission_unit = 1500;
|
||||
caps.medium = smoltcp::phy::Medium::Ip;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace netrunner_client_core {};
|
||||
namespace netrunner_client {};
|
||||
|
||||
interface SessionManager {
|
||||
constructor();
|
||||
+59
-42
@@ -43,49 +43,78 @@ impl Tun {
|
||||
Ok((writer, reader))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn setup_routing(&self) -> io::Result<()> {
|
||||
fn get_route_part<'a>(parts: &'a [&'a str], key: &str) -> Option<&'a str> {
|
||||
parts
|
||||
.iter()
|
||||
.position(|&x| x == key)
|
||||
.and_then(|i| parts.get(i + 1))
|
||||
.copied()
|
||||
}
|
||||
|
||||
#[cfg(feature = "desktop")]
|
||||
pub fn setup_routing(&self, remote_address: &str) -> io::Result<()> {
|
||||
use std::process::Command;
|
||||
|
||||
// 1. Удаляем существующий default-маршрут (чтобы не было конфликтов)
|
||||
// Игнорируем ошибку, если его вдруг нет
|
||||
info!(
|
||||
"Начинаем настройку маршрутизации для прокси: {}",
|
||||
remote_address
|
||||
);
|
||||
|
||||
// 1. Находим текущий маршрут до прокси (до изменения default)
|
||||
let output = Command::new("ip")
|
||||
.args(&["route", "get", remote_address])
|
||||
.output()?;
|
||||
let route_info = String::from_utf8_lossy(&output.stdout);
|
||||
let parts: Vec<&str> = route_info.split_whitespace().collect();
|
||||
|
||||
let dev = Self::get_route_part(&parts, "dev").unwrap_or("eth0");
|
||||
let via = Self::get_route_part(&parts, "via");
|
||||
|
||||
info!("Обнаружен физический маршрут: dev={}, via={:?}", dev, via);
|
||||
|
||||
// 2. Добавляем статическое исключение для прокси
|
||||
info!("Добавляем статический маршрут для прокси...");
|
||||
let mut proxy_route = vec!["ip", "route", "add", remote_address, "dev", dev];
|
||||
if let Some(gw) = via {
|
||||
proxy_route.extend_from_slice(&["via", gw]);
|
||||
}
|
||||
let status = Command::new("sudo").args(proxy_route).status()?;
|
||||
if !status.success() {
|
||||
warn!("Маршрут к прокси уже существует или возникла ошибка (это нормально).");
|
||||
}
|
||||
|
||||
// 3. Удаляем старый default, если он есть
|
||||
info!("Переключаем default маршрут на tun0...");
|
||||
let _ = Command::new("sudo")
|
||||
.args(&["ip", "route", "del", "default"])
|
||||
.status();
|
||||
|
||||
// 2. Добавляем tun0 как ГЛАВНЫЙ маршрут (метрика 1 — самый высокий приоритет)
|
||||
let _ = Command::new("sudo")
|
||||
// 4. Устанавливаем tun0 как основной default
|
||||
let status = Command::new("sudo")
|
||||
.args(&[
|
||||
"ip", "route", "add", "default", "via", "10.0.0.2", "dev", "tun0", "metric", "1",
|
||||
])
|
||||
.status();
|
||||
.status()?;
|
||||
if status.success() {
|
||||
info!("TUN успешно установлен как основной default.");
|
||||
} else {
|
||||
error!("Не удалось установить tun0 как default!");
|
||||
}
|
||||
|
||||
// 3. Добавляем eth0 как РЕЗЕРВНЫЙ маршрут (метрика 100 — низкий приоритет)
|
||||
// ВАЖНО: Тебе нужно знать IP шлюза твоего eth0.
|
||||
// Если ты не знаешь его заранее, можешь попробовать вытащить его из `ip route`
|
||||
// или просто оставить как есть, если eth0 — единственный физический интерфейс.
|
||||
let _ = Command::new("sudo")
|
||||
.args(&[
|
||||
"ip",
|
||||
"route",
|
||||
"add",
|
||||
"default",
|
||||
"via",
|
||||
"172.18.144.1",
|
||||
"dev",
|
||||
"eth0",
|
||||
"metric",
|
||||
"100",
|
||||
])
|
||||
.status();
|
||||
// 5. Добавляем резервный маршрут через физический интерфейс
|
||||
if let Some(gw) = via {
|
||||
info!("Добавляем резервный маршрут через {} с метрикой 100", dev);
|
||||
let _ = Command::new("sudo")
|
||||
.args(&[
|
||||
"ip", "route", "add", "default", "via", gw, "dev", dev, "metric", "100",
|
||||
])
|
||||
.status();
|
||||
}
|
||||
|
||||
info!(
|
||||
"Маршрутизация настроена: tun0 (metric 1) -> основной, eth0 (metric 100) -> резервный"
|
||||
);
|
||||
info!("Маршрутизация полностью настроена.");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(feature = "desktop")]
|
||||
pub fn setup_dns_redirection(&self) -> io::Result<()> {
|
||||
// 1. Создаем временный файл resolv.conf
|
||||
// Мы говорим системе: "Твой DNS-сервер теперь 10.0.0.1" (твой TUN-IP)
|
||||
@@ -99,16 +128,4 @@ impl Tun {
|
||||
info!("DNS перенаправлен на 10.0.0.1");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn setup_routing(&self) -> io::Result<()> {
|
||||
info!("Skipping routing setup on Android (handled by VpnService)");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn setup_dns_redirection(&self) -> io::Result<()> {
|
||||
info!("Skipping DNS setup on Android (handled by VpnService)");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user