value updates and logs
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
use bytes::{Buf, Bytes, BytesMut};
|
use bytes::{Buf, Bytes, BytesMut};
|
||||||
use netrunner_core::proxy::connection::TCP_BUF_SIZE;
|
|
||||||
use smoltcp::iface::SocketHandle;
|
use smoltcp::iface::SocketHandle;
|
||||||
use smoltcp::socket::tcp;
|
use smoltcp::socket::tcp;
|
||||||
use tokio::sync::{mpsc, oneshot};
|
use tokio::sync::{mpsc, oneshot};
|
||||||
|
|
||||||
|
use crate::connections::CHANNEL_CAPACITY;
|
||||||
|
|
||||||
pub enum ConnectionState {
|
pub enum ConnectionState {
|
||||||
Established,
|
Established,
|
||||||
Handshaking,
|
Handshaking,
|
||||||
@@ -14,16 +15,14 @@ pub enum ConnectionState {
|
|||||||
pub struct TcpConnection {
|
pub struct TcpConnection {
|
||||||
pub handle: SocketHandle,
|
pub handle: SocketHandle,
|
||||||
state: ConnectionState,
|
state: ConnectionState,
|
||||||
// UPLOAD: Ограниченный канал для передачи данных наружу
|
|
||||||
tx: mpsc::Sender<Bytes>,
|
tx: mpsc::Sender<Bytes>,
|
||||||
// DOWNLOAD: Канал для приема данных из сети
|
|
||||||
rx: mpsc::Receiver<Bytes>,
|
rx: mpsc::Receiver<Bytes>,
|
||||||
pending_data: BytesMut,
|
pending_data: BytesMut,
|
||||||
handshake_rx: Option<oneshot::Receiver<()>>,
|
handshake_rx: Option<oneshot::Receiver<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_PENDING: usize = 32 * 512 * 1024;
|
const MAX_PENDING: usize = 64 * 1024;
|
||||||
const TCP_CHUNK_SIZE: usize = 65536;
|
const TCP_CHUNK_SIZE: usize = 1024 * 16;
|
||||||
|
|
||||||
impl TcpConnection {
|
impl TcpConnection {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
@@ -34,8 +33,8 @@ impl TcpConnection {
|
|||||||
mpsc::Sender<Bytes>,
|
mpsc::Sender<Bytes>,
|
||||||
oneshot::Sender<()>,
|
oneshot::Sender<()>,
|
||||||
) {
|
) {
|
||||||
let (tx_to_net, rx_from_smol) = mpsc::channel::<Bytes>(TCP_BUF_SIZE);
|
let (tx_to_net, rx_from_smol) = mpsc::channel::<Bytes>(CHANNEL_CAPACITY);
|
||||||
let (tx_to_smol, rx_from_net) = mpsc::channel::<Bytes>(TCP_BUF_SIZE);
|
let (tx_to_smol, rx_from_net) = mpsc::channel::<Bytes>(CHANNEL_CAPACITY);
|
||||||
let (handshake_tx, handshake_rx) = oneshot::channel();
|
let (handshake_tx, handshake_rx) = oneshot::channel();
|
||||||
|
|
||||||
let conn = Self {
|
let conn = Self {
|
||||||
@@ -107,74 +106,92 @@ impl TcpConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll_and_process(&mut self, socket: &mut tcp::Socket) {
|
fn poll_and_process(&mut self, socket: &mut tcp::Socket) {
|
||||||
// 1. UPLOAD: Чанкинг и Backpressure
|
|
||||||
if socket.can_recv() {
|
|
||||||
while socket.can_recv() {
|
while socket.can_recv() {
|
||||||
let mut channel_full = false;
|
let mut full = false;
|
||||||
let mut channel_closed = false;
|
|
||||||
|
|
||||||
let _ = socket.recv(|data| {
|
// Используем recv_slice для контроля размера чанка
|
||||||
if data.is_empty() {
|
let mut temp = [0u8; TCP_CHUNK_SIZE];
|
||||||
return (0, ());
|
|
||||||
|
// Peek, чтобы проверить, сможем ли мы отправить данные, прежде чем извлечь их
|
||||||
|
if let Ok(n) = socket.peek_slice(&mut temp) {
|
||||||
|
if n == 0 {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let chunk_size = std::cmp::min(data.len(), TCP_CHUNK_SIZE);
|
let chunk = Bytes::copy_from_slice(&temp[..n]);
|
||||||
let chunk = &data[..chunk_size];
|
match self.tx.try_send(chunk) {
|
||||||
|
Ok(_) => {
|
||||||
match self.tx.try_send(Bytes::copy_from_slice(chunk)) {
|
// Только если успешно отправили в канал, удаляем данные из сокета
|
||||||
Ok(_) => (chunk_size, ()),
|
socket.recv_slice(&mut temp[..n]).unwrap();
|
||||||
|
}
|
||||||
Err(mpsc::error::TrySendError::Full(_)) => {
|
Err(mpsc::error::TrySendError::Full(_)) => {
|
||||||
channel_full = true;
|
full = true; // Канал забит, сработает Backpressure в smoltcp
|
||||||
(0, ()) // Оставляем данные в smoltcp
|
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
channel_closed = true;
|
self.state = ConnectionState::Closed;
|
||||||
(0, ())
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if channel_full || channel_closed {
|
if full {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_pending = self.pending_data.len();
|
||||||
|
|
||||||
|
// Считаем % заполненности для логирования
|
||||||
|
let fill_ratio = (current_pending as f32 / MAX_PENDING as f32) * 100.0;
|
||||||
|
|
||||||
|
if current_pending >= MAX_PENDING {
|
||||||
|
// Состояние активного Backpressure
|
||||||
|
netrunner_logger::warn!(
|
||||||
|
%self.handle,
|
||||||
|
"Backpressure ACTIVE: Buffer is FULL ({} bytes). Stalling RX channel.",
|
||||||
|
current_pending
|
||||||
|
);
|
||||||
|
} else if fill_ratio > 80.0 {
|
||||||
|
// Состояние Bufferbloat (буфер почти полон, пакеты задерживаются)
|
||||||
|
netrunner_logger::info!(
|
||||||
|
%self.handle,
|
||||||
|
"Bufferbloat Warning: Buffer {:.1}% full ({} bytes). Latency increasing.",
|
||||||
|
fill_ratio, current_pending
|
||||||
|
);
|
||||||
|
|
||||||
|
// Продолжаем читать, пока есть хоть какое-то место
|
||||||
|
while let Ok(data) = self.rx.try_recv() {
|
||||||
|
self.pending_data.extend_from_slice(&data);
|
||||||
|
if self.pending_data.len() >= MAX_PENDING {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Обычный режим
|
||||||
|
while let Ok(data) = self.rx.try_recv() {
|
||||||
|
self.pending_data.extend_from_slice(&data);
|
||||||
|
if self.pending_data.len() >= MAX_PENDING {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. DOWNLOAD: Сброс ограниченного канала в буфер
|
// 3. DOWNLOAD: Отправка накопленного буфера в smoltcp
|
||||||
while let Ok(data) = self.rx.try_recv() {
|
|
||||||
if self.pending_data.is_empty() && socket.can_send() {
|
|
||||||
match socket.send_slice(&data) {
|
|
||||||
Ok(n) if n < data.len() => {
|
|
||||||
self.pending_data.extend_from_slice(&data[n..]);
|
|
||||||
}
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(_) => {
|
|
||||||
self.pending_data.extend_from_slice(&data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.pending_data.extend_from_slice(&data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.pending_data.len() > MAX_PENDING {
|
|
||||||
netrunner_logger::error!(
|
|
||||||
%self.handle,
|
|
||||||
"TCP Buffer overflow ({} bytes). Dropping connection.",
|
|
||||||
self.pending_data.len()
|
|
||||||
);
|
|
||||||
socket.abort();
|
|
||||||
self.state = ConnectionState::Closed;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. DOWNLOAD: Отправка буфера в smoltcp
|
|
||||||
if !self.pending_data.is_empty() && socket.can_send() {
|
if !self.pending_data.is_empty() && socket.can_send() {
|
||||||
match socket.send_slice(&self.pending_data) {
|
match socket.send_slice(&self.pending_data) {
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
self.pending_data.advance(n);
|
self.pending_data.advance(n);
|
||||||
|
|
||||||
|
// Лог освобождения (опционально, чтобы видеть, что пробка рассасывается)
|
||||||
|
if n > 0 && self.pending_data.len() < (MAX_PENDING / 2) && fill_ratio > 90.0 {
|
||||||
|
netrunner_logger::info!(%self.handle, "Backpressure RELIEVED: Buffer drained to {} bytes", self.pending_data.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
netrunner_logger::debug!(%self.handle, "Smoltcp socket send error: {:?}", e);
|
||||||
}
|
}
|
||||||
Err(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use netrunner_core::{
|
use netrunner_core::{
|
||||||
protocol::codec::{frame::FrameType, socks::TargetAddress},
|
protocol::codec::{frame::FrameType, socks::TargetAddress},
|
||||||
proxy::connection::{
|
proxy::connection::muxer::{MuxMessage, Muxer},
|
||||||
TCP_BUF_SIZE,
|
|
||||||
muxer::{MuxMessage, Muxer},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use netrunner_logger::{debug, info, warn};
|
use netrunner_logger::{debug, error, info, warn};
|
||||||
use smoltcp::{
|
use smoltcp::{
|
||||||
iface::{SocketHandle, SocketSet},
|
iface::{SocketHandle, SocketSet},
|
||||||
socket::{AnySocket, icmp, tcp, udp},
|
socket::{AnySocket, icmp, tcp, udp},
|
||||||
@@ -74,11 +71,10 @@ impl ConnectionManager {
|
|||||||
let local_endpoint = match socket.local_endpoint() {
|
let local_endpoint = match socket.local_endpoint() {
|
||||||
Some(ep) => ep,
|
Some(ep) => ep,
|
||||||
None => {
|
None => {
|
||||||
warn!(handle=?socket, "Attempted to resolve target for an unconnected socket");
|
warn!(handle=?socket, "Target resolution failed: socket disconnected or no local endpoint");
|
||||||
return TargetAddress::Domain("disconnected".to_string(), 0);
|
return TargetAddress::Domain("disconnected".to_string(), 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!(remote_addr = %local_endpoint.addr, remote_port = %local_endpoint.port, "SMOLTCP RAW REMOTE ENDPOINT");
|
|
||||||
|
|
||||||
let port = local_endpoint.port;
|
let port = local_endpoint.port;
|
||||||
let ip = local_endpoint.addr;
|
let ip = local_endpoint.addr;
|
||||||
@@ -86,27 +82,30 @@ impl ConnectionManager {
|
|||||||
match ip {
|
match ip {
|
||||||
smoltcp::wire::IpAddress::Ipv4(ipv4_addr) => {
|
smoltcp::wire::IpAddress::Ipv4(ipv4_addr) => {
|
||||||
let std_ip = std::net::Ipv4Addr::from(ipv4_addr);
|
let std_ip = std::net::Ipv4Addr::from(ipv4_addr);
|
||||||
|
let start = StdInstant::now();
|
||||||
|
|
||||||
debug!(ip=%std_ip, "Trying to resolve IP in FakeIpStore");
|
|
||||||
if let Some(domain) = self.fake_ip_store.lookup_by_ip(&std_ip) {
|
if let Some(domain) = self.fake_ip_store.lookup_by_ip(&std_ip) {
|
||||||
debug!(target=%domain, port=%port, "Resolved fake IP to domain");
|
debug!(ip=%std_ip, domain=%domain, elapsed=?start.elapsed(), "FakeIP match found");
|
||||||
return TargetAddress::Domain(domain, port);
|
TargetAddress::Domain(domain, port)
|
||||||
} else {
|
} else {
|
||||||
warn!(ip=%std_ip, "IP not found in FakeIpStore! SOCKS request will fail.");
|
warn!(ip=%std_ip, port=%port, "IP not found in FakeIpStore. Using raw IP (possible DNS lag)");
|
||||||
}
|
|
||||||
|
|
||||||
debug!(ip=%std_ip, port=%port, "Using raw IP target");
|
|
||||||
TargetAddress::Ipv4(std_ip, port)
|
TargetAddress::Ipv4(std_ip, port)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
smoltcp::wire::IpAddress::Ipv6(ipv6_addr) => {
|
smoltcp::wire::IpAddress::Ipv6(ipv6_addr) => {
|
||||||
let std_ip = std::net::Ipv6Addr::from(ipv6_addr);
|
let std_ip = std::net::Ipv6Addr::from(ipv6_addr);
|
||||||
debug!(ip=%std_ip, port=%port, "Using IPv6 target");
|
debug!(ip=%std_ip, port=%port, "Using raw IPv6 target");
|
||||||
TargetAddress::Ipv6(std_ip, port)
|
TargetAddress::Ipv6(std_ip, port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_sockets(&mut self, socket_set: &mut SocketSet) {
|
pub fn process_sockets(&mut self, socket_set: &mut SocketSet) {
|
||||||
|
// Добавим лог в начало цикла, если сессий много, чтобы видеть нагрузку
|
||||||
|
if !self.active_tcp_sessions.is_empty() || !self.active_udp_sessions.is_empty() {
|
||||||
|
// trace!("Processing sockets: TCP={}, UDP={}", self.active_tcp_sessions.len(), self.active_udp_sessions.len());
|
||||||
|
}
|
||||||
|
|
||||||
for (handle, socket) in socket_set.iter_mut() {
|
for (handle, socket) in socket_set.iter_mut() {
|
||||||
if let Some(tcp) = tcp::Socket::downcast_mut(socket) {
|
if let Some(tcp) = tcp::Socket::downcast_mut(socket) {
|
||||||
self.handle_tcp(handle, tcp);
|
self.handle_tcp(handle, tcp);
|
||||||
@@ -122,11 +121,9 @@ impl ConnectionManager {
|
|||||||
use tcp::State;
|
use tcp::State;
|
||||||
|
|
||||||
if socket.state() == State::Closed {
|
if socket.state() == State::Closed {
|
||||||
if self.active_tcp_sessions.contains_key(&handle) {
|
if self.active_tcp_sessions.remove(&handle).is_some() {
|
||||||
debug!(%handle, "TCP session closed, removing from active sessions");
|
info!(%handle, "TCP Session removed: local socket closed");
|
||||||
self.active_tcp_sessions.remove(&handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.sockets_to_remove.contains(&handle) {
|
if !self.sockets_to_remove.contains(&handle) {
|
||||||
self.sockets_to_remove.push(handle);
|
self.sockets_to_remove.push(handle);
|
||||||
}
|
}
|
||||||
@@ -134,30 +131,31 @@ impl ConnectionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if socket.state() == State::Established && !self.active_tcp_sessions.contains_key(&handle) {
|
if socket.state() == State::Established && !self.active_tcp_sessions.contains_key(&handle) {
|
||||||
|
let start_establish = StdInstant::now();
|
||||||
let target = self.resolve_target(socket);
|
let target = self.resolve_target(socket);
|
||||||
|
|
||||||
if let TargetAddress::Domain(d, _) = &target {
|
if let TargetAddress::Domain(d, _) = &target {
|
||||||
if d == "disconnected" {
|
if d == "disconnected" {
|
||||||
|
warn!(%handle, "Aborting socket: target unresolved");
|
||||||
socket.abort();
|
socket.abort();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(%handle, "New TCP session established for target: {:?}", target);
|
info!(%handle, target = %target, "New TCP session: Local established, starting Muxer handshake");
|
||||||
|
|
||||||
// 1. Создаем соединение и получаем каналы
|
|
||||||
let (conn, mut rx_from_smol, tx_to_smol, handshake_tx) = TcpConnection::new(handle);
|
let (conn, mut rx_from_smol, tx_to_smol, handshake_tx) = TcpConnection::new(handle);
|
||||||
self.active_tcp_sessions.insert(handle, conn);
|
self.active_tcp_sessions.insert(handle, conn);
|
||||||
|
|
||||||
// 2. Выносим логику мультиплексирования в фоновую задачу
|
|
||||||
let muxer = self.muxer.clone();
|
let muxer = self.muxer.clone();
|
||||||
let stream_id = muxer.next_id();
|
let stream_id = muxer.next_id();
|
||||||
let connect_payload = target.to_string();
|
let connect_payload = target.to_string();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let (v_tx, mut v_rx) = mpsc::channel::<Bytes>(TCP_BUF_SIZE);
|
let (v_tx, mut v_rx) = mpsc::channel::<Bytes>(CHANNEL_CAPACITY);
|
||||||
muxer.register_stream(stream_id, v_tx);
|
muxer.register_stream(stream_id, v_tx);
|
||||||
|
|
||||||
|
let send_start = StdInstant::now();
|
||||||
if muxer
|
if muxer
|
||||||
.send_to_netwrok(MuxMessage {
|
.send_to_netwrok(MuxMessage {
|
||||||
stream_id,
|
stream_id,
|
||||||
@@ -167,24 +165,25 @@ impl ConnectionManager {
|
|||||||
.await
|
.await
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
|
error!(stream_id, "Muxer: Failed to send Connect frame");
|
||||||
muxer.remove_stream(stream_id);
|
muxer.remove_stream(stream_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let first_payload =
|
// Ждем подтверждения от прокси (handshake)
|
||||||
tokio::time::timeout(Duration::from_secs(10), v_rx.recv()).await;
|
match tokio::time::timeout(Duration::from_secs(10), v_rx.recv()).await {
|
||||||
match first_payload {
|
|
||||||
Ok(Some(data)) => {
|
Ok(Some(data)) => {
|
||||||
if data.len() >= 2 && data[1] == 0x00 {
|
if data.len() >= 2 && data[1] == 0x00 {
|
||||||
|
info!(stream_id, %handle, elapsed=?send_start.elapsed(), "Muxer: Handshake success");
|
||||||
let _ = handshake_tx.send(());
|
let _ = handshake_tx.send(());
|
||||||
} else {
|
} else {
|
||||||
netrunner_logger::warn!(stream_id, "Server rejected TCP connection");
|
warn!(stream_id, "Muxer: Connection rejected by proxy server");
|
||||||
muxer.remove_stream(stream_id);
|
muxer.remove_stream(stream_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
netrunner_logger::error!(stream_id, "Timeout waiting for proxy response");
|
error!(stream_id, "Muxer: Handshake timeout (10s)");
|
||||||
muxer.remove_stream(stream_id);
|
muxer.remove_stream(stream_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -192,12 +191,15 @@ impl ConnectionManager {
|
|||||||
|
|
||||||
let to_proxy = async {
|
let to_proxy = async {
|
||||||
while let Some(data) = rx_from_smol.recv().await {
|
while let Some(data) = rx_from_smol.recv().await {
|
||||||
let msg = MuxMessage {
|
if muxer
|
||||||
|
.send_to_netwrok(MuxMessage {
|
||||||
stream_id,
|
stream_id,
|
||||||
frame_type: FrameType::Data,
|
frame_type: FrameType::Data,
|
||||||
data,
|
data,
|
||||||
};
|
})
|
||||||
if muxer.send_to_netwrok(msg).await.is_err() {
|
.await
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,18 +207,15 @@ impl ConnectionManager {
|
|||||||
|
|
||||||
let from_proxy = async {
|
let from_proxy = async {
|
||||||
while let Some(data) = v_rx.recv().await {
|
while let Some(data) = v_rx.recv().await {
|
||||||
if data.is_empty() {
|
if data.is_empty() || tx_to_smol.send(data).await.is_err() {
|
||||||
break;
|
|
||||||
}
|
|
||||||
if tx_to_smol.send(data).await.is_err() {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = to_proxy => {}
|
_ = to_proxy => debug!(stream_id, "Stream direction: SMOL -> Proxy closed"),
|
||||||
_ = from_proxy => {}
|
_ = from_proxy => debug!(stream_id, "Stream direction: Proxy -> SMOL closed"),
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = muxer
|
let _ = muxer
|
||||||
@@ -227,17 +226,19 @@ impl ConnectionManager {
|
|||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
muxer.remove_stream(stream_id);
|
muxer.remove_stream(stream_id);
|
||||||
|
debug!(stream_id, "Muxer stream fully removed");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(conn) = self.active_tcp_sessions.get_mut(&handle) {
|
if let Some(conn) = self.active_tcp_sessions.get_mut(&handle) {
|
||||||
if !conn.tick(socket) {
|
if !conn.tick(socket) {
|
||||||
debug!(%handle, "Connection tick failed, aborting.");
|
debug!(%handle, "TCP Connection tick failed (buffer full or error), aborting");
|
||||||
socket.abort();
|
socket.abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if socket.state() == State::CloseWait {
|
if socket.state() == State::CloseWait {
|
||||||
|
debug!(%handle, "Socket in CloseWait, closing locally");
|
||||||
socket.close();
|
socket.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,7 +363,7 @@ impl ConnectionManager {
|
|||||||
|
|
||||||
fn create_dynamic_tcp_socket<'a>(port: u16) -> tcp::Socket<'a> {
|
fn create_dynamic_tcp_socket<'a>(port: u16) -> tcp::Socket<'a> {
|
||||||
let buf_size = match port {
|
let buf_size = match port {
|
||||||
443 | 80 => 512 * 1024,
|
443 | 80 => 1024 * 1024 * 2,
|
||||||
22 => 32 * 1024,
|
22 => 32 * 1024,
|
||||||
53 => 16 * 1024,
|
53 => 16 * 1024,
|
||||||
_ => 128 * 1024,
|
_ => 128 * 1024,
|
||||||
@@ -377,7 +378,6 @@ impl ConnectionManager {
|
|||||||
socket.set_ack_delay(None);
|
socket.set_ack_delay(None);
|
||||||
socket
|
socket
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_create_socket_from_packet(&mut self, packet: &[u8], socket_set: &mut SocketSet) {
|
pub fn try_create_socket_from_packet(&mut self, packet: &[u8], socket_set: &mut SocketSet) {
|
||||||
let Ok(ip_packet) = Ipv4Packet::new_checked(packet) else {
|
let Ok(ip_packet) = Ipv4Packet::new_checked(packet) else {
|
||||||
return;
|
return;
|
||||||
@@ -394,16 +394,18 @@ impl ConnectionManager {
|
|||||||
let dst_addr = ip_packet.dst_addr();
|
let dst_addr = ip_packet.dst_addr();
|
||||||
|
|
||||||
if !self.has_active_tcp_session(socket_set, dst_addr.into(), dst_port) {
|
if !self.has_active_tcp_session(socket_set, dst_addr.into(), dst_port) {
|
||||||
debug!(target: "netrunner", "Dynamic TCP: Creating socket for {}:{}", dst_addr, dst_port);
|
let start_create = StdInstant::now();
|
||||||
|
|
||||||
let mut socket = Self::create_dynamic_tcp_socket(dst_port);
|
let mut socket = Self::create_dynamic_tcp_socket(dst_port);
|
||||||
let endpoint = IpListenEndpoint {
|
let endpoint = IpListenEndpoint {
|
||||||
addr: Some(dst_addr.into()),
|
addr: Some(dst_addr.into()),
|
||||||
port: dst_port,
|
port: dst_port,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(_) = socket.listen(endpoint) {
|
if socket.listen(endpoint).is_ok() {
|
||||||
socket_set.add(socket);
|
let handle = socket_set.add(socket);
|
||||||
|
debug!(%handle, "Dynamic TCP: Created for {}:{} in {:?}", dst_addr, dst_port, start_create.elapsed());
|
||||||
|
} else {
|
||||||
|
warn!("Dynamic TCP: Failed to listen on {}:{}", dst_addr, dst_port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -420,16 +422,16 @@ impl ConnectionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !self.has_active_udp_session(socket_set, dst_addr.into(), dst_port) {
|
if !self.has_active_udp_session(socket_set, dst_addr.into(), dst_port) {
|
||||||
netrunner_logger::debug!(target: "netrunner", "Dynamic UDP: Creating socket for {}:{}", dst_addr, dst_port);
|
let start_create = StdInstant::now();
|
||||||
|
|
||||||
let mut socket = Self::create_dynamic_udp_socket(dst_port);
|
let mut socket = Self::create_dynamic_udp_socket(dst_port);
|
||||||
let endpoint = IpListenEndpoint {
|
let endpoint = IpListenEndpoint {
|
||||||
addr: Some(dst_addr.into()),
|
addr: Some(dst_addr.into()),
|
||||||
port: dst_port,
|
port: dst_port,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(_) = socket.bind(endpoint) {
|
if socket.bind(endpoint).is_ok() {
|
||||||
socket_set.add(socket);
|
let handle = socket_set.add(socket);
|
||||||
|
debug!(%handle, "Dynamic UDP: Created for {}:{} in {:?}", dst_addr, dst_port, start_create.elapsed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -439,8 +441,8 @@ impl ConnectionManager {
|
|||||||
|
|
||||||
fn create_dynamic_udp_socket<'a>(port: u16) -> udp::Socket<'a> {
|
fn create_dynamic_udp_socket<'a>(port: u16) -> udp::Socket<'a> {
|
||||||
let (buf_size, packet_count) = match port {
|
let (buf_size, packet_count) = match port {
|
||||||
443 => (512 * 1024, 380), // Большой буфер для QUIC (YouTube)
|
443 => (512 * 1024, 390), // Большой буфер для QUIC (YouTube)
|
||||||
53 => (16 * 1024, 32), // DNS
|
53 => (64 * 1024, 32), // DNS
|
||||||
_ => (128 * 1024, 100),
|
_ => (128 * 1024, 100),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -501,10 +503,12 @@ impl ConnectionManager {
|
|||||||
|
|
||||||
pub fn cleanup(&mut self, socket_set: &mut SocketSet) {
|
pub fn cleanup(&mut self, socket_set: &mut SocketSet) {
|
||||||
for handle in self.sockets_to_remove.drain(..) {
|
for handle in self.sockets_to_remove.drain(..) {
|
||||||
debug!(%handle, "Memory free: removing socket from set");
|
debug!(%handle, "Cleanup: Removing socket from SocketSet and internal maps");
|
||||||
socket_set.remove(handle);
|
socket_set.remove(handle);
|
||||||
self.last_activity.remove(&handle);
|
self.last_activity.remove(&handle);
|
||||||
self.failed_until.remove(&handle);
|
self.failed_until.remove(&handle);
|
||||||
|
self.active_tcp_sessions.remove(&handle);
|
||||||
|
self.active_udp_sessions.remove(&handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ impl TunnelEngine {
|
|||||||
codec: &Arc<Mutex<Codec>>,
|
codec: &Arc<Mutex<Codec>>,
|
||||||
msg: MuxMessage,
|
msg: MuxMessage,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
const MAX_CHUNK_SIZE: usize = 16000;
|
const MAX_CHUNK_SIZE: usize = 1024 * 4;
|
||||||
|
|
||||||
let mut data = msg.data;
|
let mut data = msg.data;
|
||||||
let stream_id = msg.stream_id;
|
let stream_id = msg.stream_id;
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ pub mod engine;
|
|||||||
pub mod handler;
|
pub mod handler;
|
||||||
pub mod muxer;
|
pub mod muxer;
|
||||||
|
|
||||||
pub const TCP_BUF_SIZE: usize = 1024 * 512;
|
pub const TCP_BUF_SIZE: usize = 1024 * 32;
|
||||||
pub const UDP_BUF_SIZE: usize = 1024 * 64;
|
pub const UDP_BUF_SIZE: usize = 1024 * 8;
|
||||||
pub const MESSAGE_CHANNEL_SIZE: usize = 1024 * 16;
|
pub const MESSAGE_CHANNEL_SIZE: usize = 4;
|
||||||
|
|||||||
@@ -133,8 +133,8 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --- ИЗМЕНЕНИЯ ЗДЕСЬ: Создаем два канала ---
|
// --- ИЗМЕНЕНИЯ ЗДЕСЬ: Создаем два канала ---
|
||||||
let (control_tx, control_rx) = tokio::sync::mpsc::channel(100_000);
|
let (control_tx, control_rx) = tokio::sync::mpsc::channel(MESSAGE_CHANNEL_SIZE * 4);
|
||||||
let (data_tx, data_rx) = tokio::sync::mpsc::channel(100_000);
|
let (data_tx, data_rx) = tokio::sync::mpsc::channel(MESSAGE_CHANNEL_SIZE * 4);
|
||||||
|
|
||||||
// Передаем оба трансмиттера в Muxer
|
// Передаем оба трансмиттера в Muxer
|
||||||
let muxer = Muxer::new(control_tx, data_tx, true);
|
let muxer = Muxer::new(control_tx, data_tx, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user