clean comments
This commit is contained in:
@@ -7,19 +7,13 @@ use smoltcp::{
|
||||
};
|
||||
use std::time::Duration;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
// Добавили trace для частых логов (попакетно) и debug для состояний
|
||||
|
||||
use netrunner_logger::debug;
|
||||
|
||||
// ============================================================================
|
||||
// 1. БАЗОВАЯ СТРУКТУРА (ConnectionCore)
|
||||
// ============================================================================
|
||||
|
||||
/// Фундамент для любого соединения.
|
||||
/// Инициализирует и хранит каналы связи между smoltcp и Muxer'ом.
|
||||
pub struct ConnectionCore<T> {
|
||||
pub handle: SocketHandle,
|
||||
pub tx: mpsc::Sender<T>,
|
||||
pub rx: mpsc::Receiver<Bytes>, // Входящие из туннеля всегда байты
|
||||
pub rx: mpsc::Receiver<Bytes>,
|
||||
}
|
||||
|
||||
impl<T> ConnectionCore<T> {
|
||||
@@ -39,9 +33,6 @@ impl<T> ConnectionCore<T> {
|
||||
(core, rx_from_smol, tx_to_smol)
|
||||
}
|
||||
}
|
||||
// ============================================================================
|
||||
// 2. TCP СОЕДИНЕНИЕ (TcpConnection)
|
||||
// ============================================================================
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ConnectionState {
|
||||
@@ -57,7 +48,7 @@ pub struct TcpConnection {
|
||||
pending_data: BytesMut,
|
||||
handshake_rx: Option<oneshot::Receiver<()>>,
|
||||
chunk_buf: Vec<u8>,
|
||||
server_eof: bool, // <--- ДОБАВЛЕН ФЛАГ ОКОНЧАНИЯ ПЕРЕДАЧИ
|
||||
server_eof: bool,
|
||||
}
|
||||
|
||||
impl TcpConnection {
|
||||
@@ -110,7 +101,6 @@ impl TcpConnection {
|
||||
ConnectionState::Active => {
|
||||
self.poll_and_process(socket);
|
||||
|
||||
// Если сокет достиг финальных стадий, убиваем нашу сессию
|
||||
if matches!(socket.state(), tcp::State::Closed | tcp::State::TimeWait) {
|
||||
debug!(%self.core.handle, "TCP Socket is finished, state -> Closed");
|
||||
self.state = ConnectionState::Closed;
|
||||
@@ -129,7 +119,6 @@ impl TcpConnection {
|
||||
}
|
||||
|
||||
fn poll_and_process(&mut self, socket: &mut tcp::Socket) {
|
||||
// 1. Вычитываем данные из smoltcp и шлем в Muxer
|
||||
while socket.can_recv() {
|
||||
let mut full = false;
|
||||
|
||||
@@ -147,7 +136,6 @@ impl TcpConnection {
|
||||
full = true;
|
||||
}
|
||||
Err(_) => {
|
||||
// Канал Muxer'а закрыт
|
||||
self.server_eof = true;
|
||||
break;
|
||||
}
|
||||
@@ -161,7 +149,6 @@ impl TcpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Читаем данные из Muxer'а
|
||||
if !self.server_eof {
|
||||
loop {
|
||||
if self.pending_data.len() >= socket.send_capacity() {
|
||||
@@ -182,7 +169,6 @@ impl TcpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Пишем данные браузеру
|
||||
if !self.pending_data.is_empty() && socket.can_send() {
|
||||
match socket.send_slice(&self.pending_data) {
|
||||
Ok(n) => {
|
||||
@@ -194,9 +180,6 @@ impl TcpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
// 4. ГРАЦИОЗНОЕ ЗАКРЫТИЕ (Отправка FIN браузеру)
|
||||
// Закрываем сокет ТОЛЬКО если удаленный сервер закончил работу
|
||||
// и мы отдали все накопленные данные браузеру.
|
||||
if self.server_eof && self.pending_data.is_empty() && socket.may_send() {
|
||||
debug!(%self.core.handle, "All data flushed after server EOF, sending FIN to browser");
|
||||
socket.close();
|
||||
@@ -204,15 +187,11 @@ impl TcpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 3. UDP СОЕДИНЕНИЕ (UdpConnection)
|
||||
// ============================================================================
|
||||
|
||||
const UDP_TIMEOUT: Duration = Duration::from_secs(60);
|
||||
|
||||
pub type UdpPacketTarget = (Bytes, std::net::Ipv4Addr, u16);
|
||||
pub struct UdpConnection {
|
||||
core: ConnectionCore<UdpPacketTarget>, // Используем кортеж
|
||||
core: ConnectionCore<UdpPacketTarget>,
|
||||
last_client_endpoint: Option<IpEndpoint>,
|
||||
last_activity: std::time::Instant,
|
||||
}
|
||||
@@ -234,7 +213,7 @@ impl UdpConnection {
|
||||
|
||||
(conn, rx_from_smol, tx_to_smol)
|
||||
}
|
||||
// Вспомогательный метод для Tracker'а
|
||||
|
||||
pub fn has_client(&self, port: u16) -> bool {
|
||||
self.last_client_endpoint
|
||||
.map_or(false, |ep| ep.port == port)
|
||||
@@ -261,22 +240,17 @@ impl UdpConnection {
|
||||
}
|
||||
}
|
||||
|
||||
// Исходящие из туннеля
|
||||
if let Some(client_endpoint) = self.last_client_endpoint {
|
||||
// Проверяем can_send() перед КАЖДЫМ извлечением пакета
|
||||
while socket.can_send() {
|
||||
match self.core.rx.try_recv() {
|
||||
Ok(data) => {
|
||||
if let Err(e) = socket.send_slice(&data, client_endpoint) {
|
||||
debug!("Dropped UDP packet due to smoltcp error: {:?}", e);
|
||||
// В UDP потеря пакетов нормальна, но мы хотя бы избежали
|
||||
// слепого выкачивания всего канала
|
||||
} else {
|
||||
self.last_activity = std::time::Instant::now();
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
// Канал пуст или отключен
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,6 @@ use crate::net::{
|
||||
ip_store::FakeIpStore,
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// 1. УПРАВЛЕНИЕ СОСТОЯНИЕМ СЕССИЙ (SessionTracker)
|
||||
// ============================================================================
|
||||
struct SessionTracker {
|
||||
last_activity: HashMap<SocketHandle, StdInstant>,
|
||||
active_tcp: HashMap<SocketHandle, TcpConnection>,
|
||||
@@ -69,7 +66,7 @@ impl SessionTracker {
|
||||
self.failed_until.remove(&handle);
|
||||
self.active_tcp.remove(&handle);
|
||||
self.active_udp.remove(&handle);
|
||||
self.pending_tcp.remove(&handle); // Очищаем из pending!
|
||||
self.pending_tcp.remove(&handle);
|
||||
|
||||
if let Some(socket_id) = self.handle_to_id.remove(&handle) {
|
||||
self.inbound_tx.remove(&socket_id);
|
||||
@@ -85,7 +82,6 @@ impl SessionTracker {
|
||||
) -> bool {
|
||||
socket_set.iter().any(|(_, s)| {
|
||||
if let Some(tcp) = tcp::Socket::downcast(s) {
|
||||
// Если сокет уже привязался к клиенту, проверяем его исходные данные
|
||||
if let Some(remote) = tcp.remote_endpoint() {
|
||||
if remote.addr == src_addr && remote.port == src_port {
|
||||
return true;
|
||||
@@ -107,10 +103,6 @@ impl SessionTracker {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 2. РАЗРЕШЕНИЕ АДРЕСОВ И DNS (TargetResolver)
|
||||
// ============================================================================
|
||||
|
||||
struct TargetResolver {
|
||||
dns_handler: DnsHandler,
|
||||
fake_ip_store: FakeIpStore,
|
||||
@@ -129,58 +121,47 @@ impl TargetResolver {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 3. ФАБРИКА СОКЕТОВ (SocketFactory)
|
||||
// ============================================================================
|
||||
struct SocketFactory;
|
||||
|
||||
impl SocketFactory {
|
||||
fn create_tcp<'a>(port: u16) -> tcp::Socket<'a> {
|
||||
let max_buf = NetworkConfig::global().smoltcp_socket_buf;
|
||||
let cfg = NetworkConfig::global();
|
||||
|
||||
// Для Web-трафика используем максимум из конфига (например, 2 МБ)
|
||||
// Для остальных урезаем в 4 раза, чтобы сэкономить RAM на фоновых соединениях
|
||||
let buf_size = match port {
|
||||
443 | 80 | 8080 => max_buf,
|
||||
22 => 32 * 1024,
|
||||
53 => 16 * 1024,
|
||||
_ => max_buf,
|
||||
443 | 80 | 8080 | 1935 => cfg.tcp_buf_heavy,
|
||||
_ => cfg.tcp_buf_light,
|
||||
};
|
||||
|
||||
let mut socket = tcp::Socket::new(
|
||||
tcp::SocketBuffer::new(vec![0; buf_size]),
|
||||
tcp::SocketBuffer::new(vec![0; buf_size]),
|
||||
);
|
||||
|
||||
socket.set_nagle_enabled(false);
|
||||
socket.set_ack_delay(None);
|
||||
socket
|
||||
}
|
||||
|
||||
fn create_udp<'a>(port: u16) -> udp::Socket<'a> {
|
||||
let config = NetworkConfig::global();
|
||||
let max_buf = config.smoltcp_socket_buf;
|
||||
let payload_size = config.safe_payload_size.max(1); // Защита от деления на 0
|
||||
let cfg = NetworkConfig::global();
|
||||
|
||||
// Вычисляем размер буфера и количество пакетов
|
||||
let (buf_size, packet_count) = match port {
|
||||
443 => (max_buf, max_buf / payload_size), // QUIC/HTTP3 трафик
|
||||
53 => (64 * 1024, (64 * 1024) / payload_size), // DNS
|
||||
_ => (max_buf, max_buf / payload_size),
|
||||
let (buf_size, meta_count) = match port {
|
||||
443 | 4433 | 10000..=60000 => (cfg.udp_buf_heavy, cfg.udp_meta_heavy),
|
||||
53 | 123 => (cfg.udp_buf_light, cfg.udp_meta_light),
|
||||
_ => (cfg.udp_buf_heavy / 2, cfg.udp_meta_heavy / 2),
|
||||
};
|
||||
let packet_count = packet_count.max(32);
|
||||
|
||||
udp::Socket::new(
|
||||
udp::PacketBuffer::new(
|
||||
vec![udp::PacketMetadata::EMPTY; packet_count],
|
||||
vec![udp::PacketMetadata::EMPTY; meta_count],
|
||||
vec![0; buf_size],
|
||||
),
|
||||
udp::PacketBuffer::new(
|
||||
vec![udp::PacketMetadata::EMPTY; packet_count],
|
||||
vec![udp::PacketMetadata::EMPTY; meta_count],
|
||||
vec![0; buf_size],
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn create_icmp<'a>() -> icmp::Socket<'a> {
|
||||
icmp::Socket::new(
|
||||
icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY; 8], vec![0; 2048]),
|
||||
@@ -189,9 +170,6 @@ impl SocketFactory {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 4. ГЛАВНЫЙ КООРДИНАТОР (ConnectionManager)
|
||||
// ============================================================================
|
||||
pub struct ConnectionManager {
|
||||
tracker: SessionTracker,
|
||||
resolver: TargetResolver,
|
||||
@@ -207,8 +185,6 @@ impl ConnectionManager {
|
||||
}
|
||||
}
|
||||
|
||||
// ВАЖНО: Метод для получения данных из сети (от VPN) и инъекции их в smoltcp
|
||||
// Пытается внедрить пакет. Если канал переполнен — возвращает пакет обратно!
|
||||
pub fn try_inject_inbound(&mut self, frame: RawCastFrame) -> Result<(), RawCastFrame> {
|
||||
if frame.event != RawCastEvent::Data {
|
||||
if frame.event == RawCastEvent::Close {
|
||||
@@ -221,7 +197,6 @@ impl ConnectionManager {
|
||||
if let Some(tx) = self.tracker.inbound_tx.get(&frame.socket_id) {
|
||||
match tx.try_send(frame.payload.clone()) {
|
||||
Ok(_) => {
|
||||
// Логируем входящие данные (trace чтобы не спамить, но можно временно info)
|
||||
trace!(
|
||||
"📥 [Stream {}] Inbound data: {} bytes",
|
||||
frame.socket_id,
|
||||
@@ -251,7 +226,6 @@ impl ConnectionManager {
|
||||
pub fn setup_sockets(n_icmp: usize) -> SocketSet<'static> {
|
||||
let mut sockets = SocketSet::new(Vec::with_capacity(64));
|
||||
|
||||
// 1. Создаем ОДИН постоянный UDP сокет для перехвата DNS (чтобы не плодить их)
|
||||
let mut dns_socket = SocketFactory::create_udp(53);
|
||||
let _ = dns_socket.bind(IpListenEndpoint {
|
||||
addr: None,
|
||||
@@ -259,7 +233,6 @@ impl ConnectionManager {
|
||||
});
|
||||
sockets.add(dns_socket);
|
||||
|
||||
// 2. Создаем ICMP
|
||||
for _ in 0..n_icmp {
|
||||
sockets.add(SocketFactory::create_icmp());
|
||||
}
|
||||
@@ -339,8 +312,6 @@ impl ConnectionManager {
|
||||
}
|
||||
}
|
||||
|
||||
// В TCP мы просто открываем "слушающий" сокет на конкретный IP:Port,
|
||||
// а саму сессию туннеля запустим позже в handle_tcp, когда handshake завершится.
|
||||
fn intercept_tcp(
|
||||
&mut self,
|
||||
src: smoltcp::wire::IpAddress,
|
||||
@@ -361,7 +332,6 @@ impl ConnectionManager {
|
||||
});
|
||||
let handle = socket_set.add(socket);
|
||||
|
||||
// Засекаем время создания! Если это левый пакет, мы убьем этот сокет позже.
|
||||
self.tracker.pending_tcp.insert(handle, StdInstant::now());
|
||||
}
|
||||
}
|
||||
@@ -388,7 +358,6 @@ impl ConnectionManager {
|
||||
|
||||
let socket_id = self.tracker.generate_socket_id();
|
||||
|
||||
// ВОТ ТУТ МЫ ИЗВЛЕКАЕМ IP И ДЕЛАЕМ LOOKUP С ЛОГИРОВАНИЕМ
|
||||
let (dst_ip, target) = match dst {
|
||||
smoltcp::wire::IpAddress::Ipv4(ip) => {
|
||||
let std_ip = std::net::Ipv4Addr::from(ip);
|
||||
@@ -436,7 +405,6 @@ impl ConnectionManager {
|
||||
tokio::spawn(async move {
|
||||
info!("📡 [UDP {}] Task started for {}", socket_id, target);
|
||||
|
||||
// ВОТ ТУТ ИСПРАВЛЕН ХАРДКОД! Передаем dst_ip вместо нулей
|
||||
let mut frame = RawCastFrame::connect(LocalProtocol::Udp, socket_id, dst_ip, dst_p);
|
||||
frame.payload = bytes::Bytes::from(target.clone());
|
||||
|
||||
@@ -471,8 +439,6 @@ impl ConnectionManager {
|
||||
}
|
||||
}
|
||||
|
||||
// --- ЦИКЛ ОБРАБОТКИ СОКЕТОВ (Pumping) ---
|
||||
|
||||
pub fn process_sockets(&mut self, socket_set: &mut SocketSet) {
|
||||
for (handle, socket) in socket_set.iter_mut() {
|
||||
if let Some(s) = tcp::Socket::downcast_mut(socket) {
|
||||
@@ -480,8 +446,6 @@ impl ConnectionManager {
|
||||
} else if let Some(s) = udp::Socket::downcast_mut(socket) {
|
||||
self.handle_udp(handle, s);
|
||||
} else if let Some(s) = icmp::Socket::downcast_mut(socket) {
|
||||
// smoltcp использует один тип icmp::Socket для v4 и v6
|
||||
// разделяем логику по содержимому или конфигурации
|
||||
self.handle_icmp(handle, s);
|
||||
self.handle_icmpv6(handle, s);
|
||||
}
|
||||
@@ -493,12 +457,11 @@ impl ConnectionManager {
|
||||
if let Some(id) = self.tracker.handle_to_id.get(&handle) {
|
||||
info!("🏁 [TCP {}] Connection closed", id);
|
||||
}
|
||||
self.tracker.pending_tcp.remove(&handle); // Чистим
|
||||
self.tracker.pending_tcp.remove(&handle);
|
||||
self.tracker.queue_removal(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// УБИРАЕМ GHOST SOCKETS: Если сокет висит в Listen/SynReceived больше 20 секунд — убиваем!
|
||||
if matches!(socket.state(), tcp::State::Listen | tcp::State::SynReceived) {
|
||||
if let Some(created_at) = self.tracker.pending_tcp.get(&handle) {
|
||||
if created_at.elapsed() > std::time::Duration::from_secs(20) {
|
||||
@@ -510,11 +473,10 @@ impl ConnectionManager {
|
||||
self.tracker.queue_removal(handle);
|
||||
}
|
||||
}
|
||||
return; // Сокет еще не Established, делать тут пока нечего
|
||||
return;
|
||||
}
|
||||
|
||||
if socket.state() == tcp::State::Established {
|
||||
// Только что подключился! Удаляем из pending и переводим в active_tcp
|
||||
if self.tracker.pending_tcp.remove(&handle).is_some()
|
||||
|| !self.tracker.active_tcp.contains_key(&handle)
|
||||
{
|
||||
@@ -569,7 +531,6 @@ impl ConnectionManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Проталкиваем активные соединения
|
||||
if let Some(conn) = self.tracker.active_tcp.get_mut(&handle) {
|
||||
if !conn.tick(socket) {
|
||||
info!("⚠️ [TCP] Tick failed, aborting handle {:?}", handle);
|
||||
@@ -581,11 +542,9 @@ impl ConnectionManager {
|
||||
fn handle_udp(&mut self, handle: SocketHandle, socket: &mut udp::Socket) {
|
||||
self.tracker.last_activity.insert(handle, StdInstant::now());
|
||||
|
||||
// 1. DNS перехват с логированием
|
||||
if socket.endpoint().port == 53 {
|
||||
while let Ok((data, meta)) = socket.recv() {
|
||||
if let Some(res) = self.resolver.process_dns_query(data) {
|
||||
// Используем debug, чтобы не заливать консоль, но видеть активность
|
||||
debug!("🔍 [DNS] Resolved query for client {}", meta.endpoint);
|
||||
if let Err(e) = socket.send_slice(&res, meta) {
|
||||
warn!("❌ [DNS] Failed to send response: {:?}", e);
|
||||
@@ -595,7 +554,6 @@ impl ConnectionManager {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Жизненный цикл обычных UDP сессий
|
||||
if let Some(conn) = self.tracker.active_udp.get_mut(&handle) {
|
||||
if !conn.tick(socket) {
|
||||
if let Some(socket_id) = self.tracker.handle_to_id.get(&handle) {
|
||||
@@ -621,7 +579,6 @@ impl ConnectionManager {
|
||||
smoltcp::wire::Icmpv4Message::EchoRequest => {
|
||||
info!("🏓 [ICMPv4] Ping Request from {}", src_addr);
|
||||
|
||||
// Формируем ответ (Echo Reply)
|
||||
let mut reply_data = data.to_vec();
|
||||
let mut reply_pkt =
|
||||
smoltcp::wire::Icmpv4Packet::new_unchecked(&mut reply_data);
|
||||
@@ -654,9 +611,8 @@ impl ConnectionManager {
|
||||
|
||||
match socket.recv() {
|
||||
Ok((data, src_addr)) => {
|
||||
// 1. Извлекаем конкретно Ipv6Address из перечисления IpAddress
|
||||
let smoltcp::wire::IpAddress::Ipv6(ipv6_src) = src_addr else {
|
||||
return; // Если пришел не IPv6, выходим
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(pkt) = smoltcp::wire::Icmpv6Packet::new_checked(data) else {
|
||||
@@ -673,7 +629,6 @@ impl ConnectionManager {
|
||||
|
||||
reply_pkt.set_msg_type(smoltcp::wire::Icmpv6Message::EchoReply);
|
||||
|
||||
// 2. РАСЧЕТ ЧЕКСУММЫ (Критический момент)
|
||||
let my_v6_gateway =
|
||||
smoltcp::wire::Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1);
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ impl Engine {
|
||||
config: Config,
|
||||
caps: DeviceCapabilities,
|
||||
dns_handler: DnsHandler,
|
||||
tx_to_tunnel: mpsc::Sender<RawCastFrame>, // Куда менеджер будет слать пакеты
|
||||
rx_from_tunnel: mpsc::Receiver<RawCastFrame>, // Откуда движок будет читать пакеты
|
||||
tx_to_tunnel: mpsc::Sender<RawCastFrame>,
|
||||
rx_from_tunnel: mpsc::Receiver<RawCastFrame>,
|
||||
) -> Self {
|
||||
let now = Engine::current_time();
|
||||
|
||||
@@ -82,7 +82,6 @@ impl Engine {
|
||||
let mut stuck_frame: Option<RawCastFrame> = None;
|
||||
|
||||
loop {
|
||||
// 1. Быстро читаем из TUN
|
||||
while let Ok(token) = tun_to_engine_rx.try_recv() {
|
||||
self.manager
|
||||
.try_create_socket_from_packet(&token, &mut self.socket_set);
|
||||
@@ -91,19 +90,17 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Пытаемся протолкнуть застрявший кадр
|
||||
if let Some(frame) = stuck_frame.take() {
|
||||
if let Err(returned_frame) = self.manager.try_inject_inbound(frame) {
|
||||
stuck_frame = Some(returned_frame);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Забираем новые кадры из туннеля
|
||||
if stuck_frame.is_none() {
|
||||
while let Ok(frame) = self.rx_from_tunnel.try_recv() {
|
||||
if let Err(returned_frame) = self.manager.try_inject_inbound(frame) {
|
||||
stuck_frame = Some(returned_frame); // Возвращаем пакет в "заначку"
|
||||
break; // ТОРМОЗИМ чтение туннеля, пока канал не освободится
|
||||
stuck_frame = Some(returned_frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,17 +115,15 @@ impl Engine {
|
||||
|
||||
if matches!(result, PollResult::SocketStateChanged) {
|
||||
self.manager.cleanup(&mut self.socket_set);
|
||||
continue; // Если стейт изменился, поллим еще раз без задержек
|
||||
continue;
|
||||
}
|
||||
|
||||
self.manager.cleanup(&mut self.socket_set);
|
||||
|
||||
// 4. Правильный расчет таймаута без Busy-Loop
|
||||
let delay = self
|
||||
.interface
|
||||
.poll_delay(Self::current_time(), &self.socket_set);
|
||||
|
||||
// Создаем Future ожидания. Если None - ждем бесконечно (std::future::pending)
|
||||
let sleep_fut = async {
|
||||
if let Some(d) = delay {
|
||||
sleep(Duration::from_micros(d.micros())).await;
|
||||
@@ -137,7 +132,6 @@ impl Engine {
|
||||
}
|
||||
};
|
||||
|
||||
// 5. Умный select!
|
||||
if stuck_frame.is_none() {
|
||||
tokio::select! {
|
||||
_ = sleep_fut => {}
|
||||
@@ -154,8 +148,6 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Если буфер переполнен (stuck_frame), ждем ТОЛЬКО таймер или данные от браузера (ACK),
|
||||
// чтобы освободить буфер. Из rx_from_tunnel пока не читаем!
|
||||
tokio::select! {
|
||||
_ = sleep_fut => {}
|
||||
Some(token) = tun_to_engine_rx.recv() => {
|
||||
@@ -267,10 +259,6 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// КОНФИГУРАЦИЯ ДВИЖКА
|
||||
// ============================================================================
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EngineConfig {
|
||||
pub remote_address: String,
|
||||
@@ -311,17 +299,12 @@ impl EngineConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// БИЛДЕР ДВИЖКА
|
||||
// ============================================================================
|
||||
|
||||
pub struct EngineBuilder {
|
||||
config: EngineConfig,
|
||||
tun_device: Option<Tun>,
|
||||
}
|
||||
|
||||
impl EngineBuilder {
|
||||
/// Инициализируем билдер на основе готового конфига
|
||||
pub fn new(config: EngineConfig) -> Self {
|
||||
Self {
|
||||
config,
|
||||
@@ -329,7 +312,6 @@ impl EngineBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Передаем TUN интерфейс (зависит от платформы, поэтому не в конфиге)
|
||||
pub fn with_tun(mut self, tun: Tun) -> Self {
|
||||
self.tun_device = Some(tun);
|
||||
self
|
||||
@@ -343,13 +325,11 @@ impl EngineBuilder {
|
||||
self.config
|
||||
);
|
||||
|
||||
// 1. Инициализация DNS
|
||||
let mut dns_handler = DnsHandler::new(&self.config.cache_path);
|
||||
if let Err(e) = dns_handler.init().await {
|
||||
error!("Failed to initialize DNS blocklist: {}", e);
|
||||
}
|
||||
|
||||
// 2. Настройка системного роутинга (Опционально)
|
||||
if self.config.setup_routing {
|
||||
info!("Applying platform routing rules...");
|
||||
if let Err(e) = setup_platform_routing(&self.config.remote_address) {
|
||||
@@ -359,27 +339,19 @@ impl EngineBuilder {
|
||||
info!("Platform routing setup skipped via config.");
|
||||
}
|
||||
|
||||
// 3. Конфигурация интерфейса smoltcp
|
||||
let smol_config = Config::new(smoltcp::wire::HardwareAddress::Ip);
|
||||
let mut caps = DeviceCapabilities::default();
|
||||
caps.max_transmission_unit = self.config.mtu;
|
||||
caps.medium = smoltcp::phy::Medium::Ip;
|
||||
|
||||
// --- СОЗДАЕМ КАНАЛЫ СВЯЗИ ДВИЖОК <-> ТУННЕЛЬ ---
|
||||
// tx_to_tunnel: Движок пишет, ClientHandler читает (исходящий трафик)
|
||||
let (tx_to_tunnel, rx_for_client_handler) =
|
||||
mpsc::channel(NetworkConfig::global().muxer_capacity);
|
||||
|
||||
// tx_to_engine: ClientHandler пишет, Движок читает (входящий трафик)
|
||||
let (tx_for_client_handler, rx_from_tunnel) =
|
||||
mpsc::channel(NetworkConfig::global().muxer_capacity);
|
||||
|
||||
// 4. Подключение к серверу
|
||||
info!("Establishing secure tunnel to proxy server...");
|
||||
|
||||
// ВАЖНО: Тебе нужно добавить эти аргументы в `ClientHandler::connect`,
|
||||
// чтобы он знал, откуда забирать `RawCastFrame` для отправки на сервер,
|
||||
// и куда отдавать `RawCastFrame`, прилетевшие от сервера.
|
||||
ClientHandler::connect(
|
||||
&self.config.remote_address,
|
||||
rx_for_client_handler,
|
||||
@@ -390,7 +362,6 @@ impl EngineBuilder {
|
||||
|
||||
info!("Secure tunnel established, Muxer is ready.");
|
||||
|
||||
// 5. Инициализация и настройка Engine (передаем каналы)
|
||||
let mut engine = Engine::new(smol_config, caps, dns_handler, tx_to_tunnel, rx_from_tunnel);
|
||||
|
||||
engine.set_any_ip(self.config.any_ip);
|
||||
|
||||
Reference in New Issue
Block a user