clean project from comments

This commit is contained in:
2026-03-13 21:39:29 +07:00
parent 66036c1451
commit 0cc44d0037
34 changed files with 132 additions and 542 deletions
+1 -11
View File
@@ -4,17 +4,13 @@ use hickory_proto::rr::{RData, Record};
use crate::connections::ip_store::FakeIpStore;
pub fn handle_dns_query(data: &[u8], store: &mut FakeIpStore) -> Option<Vec<u8>> {
// 1. Парсим входящий запрос
let request = Message::from_vec(data).ok()?;
// 2. Берем первый вопрос (обычно запрос только один)
let query = request.queries().first()?;
let name = query.name().to_string().trim_end_matches('.').to_string();
// 3. Получаем Fake IP
let fake_ip = store.get_or_assign(&name);
// 4. Формируем ответ
let mut response = Message::new();
response
.set_recursion_available(true)
@@ -23,14 +19,8 @@ pub fn handle_dns_query(data: &[u8], store: &mut FakeIpStore) -> Option<Vec<u8>>
.set_response_code(ResponseCode::NoError)
.add_query(query.clone());
// Создаем запись A (IPv4)
let record = Record::from_rdata(
query.name().clone(),
1, // TTL = 1 сек
RData::A(fake_ip.into()),
);
let record = Record::from_rdata(query.name().clone(), 1, RData::A(fake_ip.into()));
response.add_answer(record);
// 5. Сериализуем обратно в байты
response.to_vec().ok()
}
+1 -1
View File
@@ -9,7 +9,7 @@ pub struct FakeIpStore {
next_ip: u32,
}
const START_IP: u32 = 0x64400001; // 100.64.0.1 (IP for Service Networks/Shared Address Space)
const START_IP: u32 = 0x64400001;
impl FakeIpStore {
pub fn new() -> Self {
+11 -19
View File
@@ -2,7 +2,7 @@ use netrunner_core::protocol::codec::socks::{SocksRequest, TargetAddress};
use smoltcp::iface::SocketHandle;
use smoltcp::socket::tcp;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream; // Твой код парсера
use tokio::net::TcpStream;
use tokio::sync::{mpsc, oneshot};
use tokio_util::sync::CancellationToken;
use tracing::{debug, info, trace, warn};
@@ -44,10 +44,9 @@ impl TcpConnection {
Err(e) => {
debug!(%handle, error = %e, "Failed to connect to proxy");
return;
} // Тут можно добавить логирование
}
};
// 2. SOCKS Handshake
if let Err(e) = SocksRequest::perform_client_handshake(&mut stream, &target_addr).await
{
debug!(%handle, error = %e, "SOCKS handshake failed");
@@ -58,10 +57,8 @@ impl TcpConnection {
debug!(%handle, "SOCKS handshake successful, starting data bridge");
// 3. Копирование данных (Bridge)
let (mut reader, mut writer) = stream.into_split();
// Читаем из канала -> Пишем в прокси
let to_proxy = async {
while let Some(data) = rx_from_smol.recv().await {
if writer.write_all(&data).await.is_err() {
@@ -70,7 +67,6 @@ impl TcpConnection {
}
};
// Читаем из прокси -> Пишем в канал для smoltcp
let from_proxy = async {
let mut buf = [0u8; 65536];
loop {
@@ -94,7 +90,7 @@ impl TcpConnection {
Self {
handle,
state: ConnectionState::Active, // Сразу переходим в Active, т.к. задача пошла
state: ConnectionState::Active,
tx: tx_to_proxy,
rx: rx_from_proxy,
pending_data: vec![],
@@ -105,7 +101,6 @@ impl TcpConnection {
pub fn tick(&mut self, socket: &mut tcp::Socket) -> bool {
let state = socket.state();
//trace!(handle=%self.handle, ?state, "Tick");
match self.state {
ConnectionState::Handshaking => {
@@ -114,23 +109,22 @@ impl TcpConnection {
Ok(_) => {
self.state = ConnectionState::Active;
self.handshake_rx = None;
return true; // Успех
return true;
}
Err(oneshot::error::TryRecvError::Empty) => return true, // Ждем
Err(oneshot::error::TryRecvError::Empty) => return true,
Err(oneshot::error::TryRecvError::Closed) => {
self.state = ConnectionState::Closed; // ФЕЙЛ
return false; // СКАЗАТЬ МЕНЕДЖЕРУ УДАЛИТЬ НАС
self.state = ConnectionState::Closed;
return false;
}
}
} else {
return false; // Если rx пропал, но мы не Active — закрываем
return false;
}
}
ConnectionState::Active => {
self.poll_and_process(socket);
// FIN от удалённой стороны
if state == tcp::State::CloseWait {
socket.close();
self.state = ConnectionState::Closed;
@@ -164,7 +158,6 @@ impl TcpConnection {
}
fn poll_and_process(&mut self, socket: &mut tcp::Socket) {
// 1. сначала читаем smoltcp
if socket.can_recv() {
let _ = socket.recv(|data| {
let len = data.len();
@@ -175,12 +168,11 @@ impl TcpConnection {
});
}
// 2. потом отправляем proxy → smoltcp
if !self.pending_data.is_empty() {
if self.pending_data.len() > MAX_PENDING {
warn!(%self.handle, "Buffer overflow! Aborting connection.");
socket.abort(); // Убиваем сокет
self.token.cancel(); // Говорим tokio-задаче умереть
socket.abort();
self.token.cancel();
return;
}
@@ -188,7 +180,7 @@ impl TcpConnection {
Ok(n) => {
self.pending_data.drain(0..n);
}
Err(_) => {} // Оставляем в pending_data на следующий тик
Err(_) => {}
}
}
+3 -10
View File
@@ -45,7 +45,6 @@ impl Session {
}
}
// --- Фабрика (SessionManager) ---
#[derive(uniffi::Object)]
pub struct SessionManager;
@@ -70,18 +69,13 @@ impl SessionManager {
} else {
info!("Creating TUN device manually");
Tun::create(|config| {
config
.tun_name("tun0")
.address((10, 0, 0, 1))
// ... настройки ...
.up();
config.tun_name("tun0").address((10, 0, 0, 1)).up();
})
.expect("Failed to init TUN")
};
setup_platform_routing(&tun_device, &remote_address);
// 2. Инициализация сети
let config = Config::new(smoltcp::wire::HardwareAddress::Ip);
let mut caps = DeviceCapabilities::default();
caps.max_transmission_unit = 1500;
@@ -97,13 +91,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);
engine.set_transparent_mode();
@@ -112,7 +106,6 @@ impl SessionManager {
info!("Engine activated");
// 4. Главный цикл с поддержкой остановки
tokio::select! {
res = engine.run(tun_device) => {
error!("Engine loop terminated unexpectedly: {:?}", res);
+1 -5
View File
@@ -13,7 +13,6 @@ use tracing::{error, info};
#[tokio::main]
async fn main() {
// 1. Инициализируем систему логирования
logger_init();
info!("Initializing NetRunner Stack...");
let tun_device = Tun::create(|config| {
@@ -46,8 +45,6 @@ async fn main() {
let proxy_ip = network.get_self_local_address();
// 2. ВЫНОСИМ СЕТЬ В ОТДЕЛЬНЫЙ ЦИКЛ
// Это запустит SOCKS5 сервер и TLS туннель параллельно движку
tokio::spawn(async move {
info!("Network thread started");
network.run().await;
@@ -56,11 +53,10 @@ async fn main() {
let mut engine = Engine::new(config, caps, proxy_ip);
engine.set_any_ip(true);
engine.set_transparent_mode();
engine.set_default_gateway(Ipv4Addr::new(10, 0, 0, 2)); // to smoltcp
engine.set_default_gateway(Ipv4Addr::new(10, 0, 0, 2));
engine.activate();
info!("Stack IP initialized: 10.0.0.2");
// 5. Запуск
info!("Engine starting process loop...");
engine.run(tun_device).await;
}
+1 -1
View File
@@ -1,4 +1,4 @@
use crate::tun::tun::Tun; // Убедись, что путь к Tun верный
use crate::tun::tun::Tun;
use std::io;
pub fn setup_platform_routing(tun_device: &Tun, remote_address: &str) -> io::Result<()> {
+5 -22
View File
@@ -19,7 +19,7 @@ use crate::{
pub struct ConnectionManager {
last_activity: HashMap<SocketHandle, StdInstant>,
active_tcp_sessions: HashMap<SocketHandle, TcpConnection>,
//active_udp_sessions: HashMap<SocketHandle, UdpSession>,
fake_ip_store: FakeIpStore,
proxy_ip: String,
failed_until: HashMap<SocketHandle, StdInstant>,
@@ -37,7 +37,6 @@ impl ConnectionManager {
}
pub fn start_listening(&mut self, socket_set: &mut SocketSet) {
for (_, socket) in socket_set.iter_mut() {
// Обработка TCP (как было)
if let Some(tcp) = tcp::Socket::downcast_mut(socket) {
if !tcp.is_open() {
let endpoint = IpListenEndpoint {
@@ -46,11 +45,8 @@ impl ConnectionManager {
};
let _ = tcp.listen(endpoint);
}
}
// Добавляем обработку UDP
else if let Some(udp) = udp::Socket::downcast_mut(socket) {
} else if let Some(udp) = udp::Socket::downcast_mut(socket) {
if !udp.is_open() {
// Биндим на 53 порт, чтобы ловить DNS-запросы
let endpoint = IpListenEndpoint {
addr: None,
port: 53,
@@ -65,12 +61,11 @@ impl ConnectionManager {
}
fn resolve_target(&self, socket: &tcp::Socket) -> TargetAddress {
// Безопасно получаем эндпоинт
let local_endpoint = match socket.local_endpoint() {
Some(ep) => ep,
None => {
warn!(handle=?socket, "Attempted to resolve target for an unconnected socket");
// Возвращаем дефолт, чтобы не падать
return TargetAddress::Domain("disconnected".to_string(), 0);
}
};
@@ -116,11 +111,10 @@ impl ConnectionManager {
fn handle_tcp(&mut self, handle: SocketHandle, socket: &mut tcp::Socket) {
use tcp::State;
// 1. Если сокет закрыт, просто чистим и возвращаем в LISTEN
if socket.state() == State::Closed {
if let Some(until) = self.failed_until.get(&handle) {
if StdInstant::now() < *until {
return; // Сокет в штрафе, не открываем его
return;
}
}
@@ -130,15 +124,11 @@ impl ConnectionManager {
return;
}
// 2. Если сокет установлен, но в менеджере нет записи
if socket.state() == State::Established && !self.active_tcp_sessions.contains_key(&handle) {
let target = self.resolve_target(socket);
// ВАЖНО: Тут можно добавить проверку: если target "плохой" или не резолвится,
// сразу убиваем сокет, чтобы не зацикливаться.
if let TargetAddress::Domain(d, _) = &target {
if d == "disconnected" {
// Или другая логика проверки
socket.abort();
return;
}
@@ -148,13 +138,11 @@ 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) {
// Если tick вернул false, значит сессия завершена или произошла ошибка в tokio-задаче
debug!(%handle, "Connection handshake failed or closed, aborting socket.");
self.active_tcp_sessions.remove(&handle);
socket.abort(); // Принудительно закрываем "битый" сокет
socket.abort();
self.failed_until
.insert(handle, StdInstant::now() + Duration::from_secs(5));
}
@@ -164,7 +152,6 @@ impl ConnectionManager {
socket.abort();
}
// 4. Обработка FIN
if socket.state() == State::CloseWait {
socket.close();
}
@@ -211,20 +198,16 @@ impl ConnectionManager {
}
pub fn setup_sockets(n_tcp: usize, n_udp: usize, n_icmp: usize) -> SocketSet<'static> {
// Создаем хранилище с запасом на все типы сокетов
let mut sockets = SocketSet::new(Vec::with_capacity(n_tcp + n_udp + n_icmp));
// 1. Добавляем TCP сокеты
for _ in 0..n_tcp {
sockets.add(Self::create_tcp_socket());
}
// 2. Добавляем UDP сокеты
for _ in 0..n_udp {
sockets.add(Self::create_udp_socket());
}
// 3. Добавляем ICMP сокет
for _ in 0..n_icmp {
sockets.add(Self::create_icmp_socket());
}
-5
View File
@@ -1,5 +1,3 @@
//! Virtual Device for receiving packets from tun
use std::{
marker::PhantomData,
mem,
@@ -119,9 +117,6 @@ impl phy::TxToken for VirtTxToken<'_> {
}
}
// Maximum number of TokenBuffer cached globally.
//
// Each of them has capacity 65536 (defined in tun/mod.rs), so 64 * 65536 = 4MB.
const TOKEN_BUFFER_LIST_MAX_SIZE: usize = 64;
static TOKEN_BUFFER_LIST: LazyLock<Mutex<Vec<BytesMut>>> = LazyLock::new(|| Mutex::new(Vec::new()));
+1 -1
View File
@@ -154,7 +154,7 @@ impl Engine {
pub fn set_transparent_mode(&mut self) {
self.interface.update_ip_addrs(|addrs| {
addrs.clear();
//accept all internet
addrs
.push(IpCidr::new(IpAddress::v4(10, 0, 0, 2), 24))
.unwrap();
+2 -10
View File
@@ -32,8 +32,8 @@ impl Tun {
pub fn from_android_fd(fd: i32) -> io::Result<Self> {
let mut config = Configuration::default();
config.raw_fd(fd); // Передаем дескриптор, который нам дал Android VpnService
config.up(); // Убеждаемся, что он поднят
config.raw_fd(fd);
config.up();
Self::new(&config)
}
@@ -60,7 +60,6 @@ impl Tun {
remote_address
);
// 1. Находим текущий маршрут до прокси (до изменения default)
let output = Command::new("ip")
.args(&["route", "get", remote_address])
.output()?;
@@ -72,7 +71,6 @@ impl Tun {
info!("Обнаружен физический маршрут: dev={}, via={:?}", dev, via);
// 2. Добавляем статическое исключение для прокси
info!("Добавляем статический маршрут для прокси...");
let mut proxy_route = vec!["ip", "route", "add", remote_address, "dev", dev];
if let Some(gw) = via {
@@ -83,13 +81,11 @@ impl Tun {
warn!("Маршрут к прокси уже существует или возникла ошибка (это нормально).");
}
// 3. Удаляем старый default, если он есть
info!("Переключаем default маршрут на tun0...");
let _ = Command::new("sudo")
.args(&["ip", "route", "del", "default"])
.status();
// 4. Устанавливаем tun0 как основной default
let status = Command::new("sudo")
.args(&[
"ip", "route", "add", "default", "via", "10.0.0.2", "dev", "tun0", "metric", "1",
@@ -101,7 +97,6 @@ impl Tun {
error!("Не удалось установить tun0 как default!");
}
// 5. Добавляем резервный маршрут через физический интерфейс
if let Some(gw) = via {
info!("Добавляем резервный маршрут через {} с метрикой 100", dev);
let _ = Command::new("sudo")
@@ -116,11 +111,8 @@ impl Tun {
}
#[cfg(feature = "desktop")]
pub fn setup_dns_redirection(&self) -> io::Result<()> {
// 1. Создаем временный файл resolv.conf
// Мы говорим системе: "Твой DNS-сервер теперь 10.0.0.1" (твой TUN-IP)
let _ = std::fs::write("/tmp/resolv.conf.netrunner", "nameserver 10.0.0.2\n");
// 2. Применяем его (для Linux/systemd)
let _ = std::process::Command::new("sudo")
.args(&["cp", "/tmp/resolv.conf.netrunner", "/etc/resolv.conf"])
.status();