stable connection

This commit is contained in:
2026-04-03 18:53:13 +07:00
parent dfac8ebc23
commit 2db4ba1e9d
14 changed files with 125 additions and 204 deletions
+1 -1
View File
@@ -77,7 +77,7 @@ impl SessionManager {
cache_dir: String,
) -> Arc<Session> {
netrunner_logger::Logger::init(None);
netrunner_logger::Logger::global().set_level("info"); // Поменял на info для дебага
netrunner_logger::Logger::global().set_level("info");
let runtime = get_runtime();
let cancel_token = CancellationToken::new();
+1 -11
View File
@@ -209,7 +209,6 @@ impl TcpConnection {
tx_tunnel: mpsc::Sender<RawCastFrame>,
) {
tokio::spawn(async move {
// 1. Формируем и отправляем кадр на установку соединения
let mut frame = RawCastFrame::connect(LocalProtocol::Tcp, socket_id, dst_ip, dst_port);
frame.payload = Bytes::from(target);
@@ -218,10 +217,8 @@ impl TcpConnection {
return;
}
// 2. Сигнализируем ConnectionManager, что запрос в туннель ушел успешно
let _ = handshake_tx.send(());
// 3. Цикл пересылки данных из smoltcp -> туннель
while let Some(data) = rx_smol.recv().await {
let data_frame = RawCastFrame::data(
LocalProtocol::Tcp,
@@ -232,7 +229,7 @@ impl TcpConnection {
);
if tx_tunnel.send(data_frame).await.is_err() {
break; // Туннель закрыт
break;
}
}
@@ -328,7 +325,6 @@ impl UdpConnection {
tokio::spawn(async move {
debug!("📡 [UDP {}] Task started for {}", socket_id, target);
// 1. Регистрация UDP сессии в туннеле
let mut frame = RawCastFrame::connect(LocalProtocol::Udp, socket_id, dst_ip, dst_port);
frame.payload = Bytes::from(target);
@@ -337,8 +333,6 @@ impl UdpConnection {
return;
}
// 2. Цикл пересылки пакетов
// rx_smol отдает кортеж (данные, ip, порт)
while let Some((data, ip, port)) = rx_smol.recv().await {
let data_frame =
RawCastFrame::data(LocalProtocol::Udp, socket_id, ip, port, data.to_vec());
@@ -366,12 +360,9 @@ impl IcmpResponder {
return;
}
// 1. Сначала достаем данные и адрес
let result = socket.recv();
if let Ok((data, src_addr)) = result {
// 2. Копируем данные в Vec, чтобы разорвать связь с буфером сокета.
// Теперь заимствование `socket` от метода .recv() закончилось.
let payload = data.to_vec();
match src_addr {
@@ -381,7 +372,6 @@ impl IcmpResponder {
}
}
// Принимаем Vec<u8>, чтобы не делать to_vec() второй раз внутри
fn reply_v4(socket: &mut icmp::Socket, mut payload: Vec<u8>, src: IpAddress) {
if let Ok(pkt) = Icmpv4Packet::new_checked(&payload) {
if pkt.msg_type() == Icmpv4Message::EchoRequest {
-3
View File
@@ -162,7 +162,6 @@ impl DnsHandler {
.set_recursion_available(true)
.add_query(query.clone());
// 1. Проверка блокировок
if self.forbidden_suffixes.iter().any(|s| name.ends_with(s))
|| self.block_list.contains(&name)
{
@@ -171,7 +170,6 @@ impl DnsHandler {
return res.to_vec().ok();
}
// 2. Генерация Fake IP для A-записей
if query.query_type() == RecordType::A {
let fake_ip = store.get_or_assign(&name);
res.add_answer(Record::from_rdata(
@@ -181,7 +179,6 @@ impl DnsHandler {
));
res.set_response_code(ResponseCode::NoError);
} else {
// Для остальных типов записей (AAAA и т.д.) просто возвращаем пустой NoError или NXDomain
res.set_response_code(ResponseCode::NoError);
}
+1 -4
View File
@@ -289,7 +289,7 @@ impl EngineConfig {
pub struct EngineBuilder {
config: EngineConfig,
tun_device: Option<Tun>,
// Добавляем возможность прокинуть кастомную фабрику сокетов
socket_factory: Option<Arc<dyn SocketProvider>>,
}
@@ -344,13 +344,10 @@ impl EngineBuilder {
.map_err(|e| format!("Failed to establish secure tunnel: {}", e))?;
let factory = self.socket_factory.unwrap_or_else(|| {
// 1. Разыменовываем ссылку и клонируем данные в новый объект
let config_owned = (*NetworkConfig::global()).clone();
// 2. Оборачиваем во владеющий Arc
let config = Arc::new(config_owned);
// Теперь типы совпадают: Arc<NetworkConfig> -> SmolSocketFactory::new
Arc::new(SmolSocketFactory::new(config))
});
+6 -9
View File
@@ -19,7 +19,7 @@ pub struct SessionTracker {
active_udp: HashMap<SocketHandle, UdpConnection>,
inbound_tx: HashMap<u64, mpsc::Sender<Bytes>>,
handle_to_id: HashMap<SocketHandle, u64>,
// 🔥 ДОБАВЛЕНО: Обратный маппинг, чтобы находить сокет по ID из туннеля
id_to_handle: HashMap<u64, SocketHandle>,
pending_tcp: HashMap<SocketHandle, StdInstant>,
to_remove: Vec<SocketHandle>,
@@ -34,7 +34,7 @@ impl SessionTracker {
active_udp: HashMap::new(),
inbound_tx: HashMap::new(),
handle_to_id: HashMap::new(),
id_to_handle: HashMap::new(), // Инициализация
id_to_handle: HashMap::new(),
pending_tcp: HashMap::new(),
to_remove: Vec::new(),
next_socket_id: 1,
@@ -60,10 +60,10 @@ impl SessionTracker {
) {
self.pending_tcp.remove(&handle);
self.handle_to_id.insert(handle, id);
self.id_to_handle.insert(id, handle); // 🔥 Регистрация обратного индекса
self.id_to_handle.insert(id, handle);
self.active_tcp.insert(handle, conn);
self.inbound_tx.insert(id, tx);
self.last_activity.insert(handle, StdInstant::now()); // Для TCP тоже полезно
self.last_activity.insert(handle, StdInstant::now());
}
pub fn register_udp(
@@ -74,7 +74,7 @@ impl SessionTracker {
tx: mpsc::Sender<Bytes>,
) {
self.handle_to_id.insert(handle, id);
self.id_to_handle.insert(id, handle); // 🔥 Регистрация обратного индекса
self.id_to_handle.insert(id, handle);
self.active_udp.insert(handle, conn);
self.inbound_tx.insert(id, tx);
self.last_activity.insert(handle, StdInstant::now());
@@ -128,7 +128,7 @@ impl SessionTracker {
pub fn close_tunnel_session(&mut self, id: u64) {
self.inbound_tx.remove(&id);
// 🔥 ИСПРАВЛЕНО: Теперь мы реально находим сокет и ставим его в очередь на удаление
if let Some(handle) = self.id_to_handle.remove(&id) {
self.queue_removal(handle);
}
@@ -140,7 +140,6 @@ impl SessionTracker {
}
}
// 🔥 ДОБАВЛЕНО: Сборщик мусора для залипших сокетов
pub fn enforce_idle_timeouts(&mut self, timeout: Duration) {
let now = StdInstant::now();
let mut ghosts = Vec::new();
@@ -159,8 +158,6 @@ impl SessionTracker {
pub fn cleanup(&mut self, socket_set: &mut SocketSet) {
for handle in self.to_remove.drain(..) {
// Удаление из socket_set автоматически делает abort() внутри smoltcp
// и освобождает память пула/буферов
socket_set.remove(handle);
self.active_tcp.remove(&handle);
+3 -5
View File
@@ -46,17 +46,15 @@ impl SmolSocketFactory {
pub fn new(config: Arc<NetworkConfig>) -> Self {
Self {
config,
// Пул на 128 тяжелых буферов. Если нужно больше — queue вернет ошибку,
// и мы просто отдадим память ОС (что безопасно).
heavy_pool: Arc::new(ArrayQueue::new(128)),
}
}
/// Берем буфер из пула или создаем новый, если пул пуст
fn alloc_buf(&self, size: usize) -> Vec<u8> {
if size == self.config.tcp_buf_heavy {
if let Some(mut buf) = self.heavy_pool.pop() {
buf.fill(0); // Очищаем данные от прошлой сессии
buf.fill(0);
return buf;
}
}
@@ -144,7 +142,7 @@ impl SocketProvider for SmolSocketFactory {
fn create_base_set(&self, n_icmp: usize) -> SocketSet<'static> {
let mut sockets = SocketSet::new(Vec::with_capacity(128));
sockets.add(self.create_bound_udp(None, 53)); // DNS
sockets.add(self.create_bound_udp(None, 53));
for _ in 0..n_icmp {
sockets.add(self.create_icmp());
}