dash map in muxer
This commit is contained in:
Generated
+21
@@ -597,6 +597,20 @@ dependencies = [
|
|||||||
"syn 2.0.116",
|
"syn 2.0.116",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dashmap"
|
||||||
|
version = "6.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"hashbrown 0.14.5",
|
||||||
|
"lock_api",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "data-encoding"
|
name = "data-encoding"
|
||||||
version = "2.10.0"
|
version = "2.10.0"
|
||||||
@@ -984,6 +998,12 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.15.5"
|
||||||
@@ -1525,6 +1545,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chacha20poly1305",
|
"chacha20poly1305",
|
||||||
|
"dashmap",
|
||||||
"hex",
|
"hex",
|
||||||
"hkdf",
|
"hkdf",
|
||||||
"hmac",
|
"hmac",
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ impl TcpConnection {
|
|||||||
// ИСПРАВЛЕНИЕ: Даем Муксеру ограниченный канал, как он и просит (тип mpsc::Sender)
|
// ИСПРАВЛЕНИЕ: Даем Муксеру ограниченный канал, как он и просит (тип mpsc::Sender)
|
||||||
// Делаем его достаточно вместительным (1024)
|
// Делаем его достаточно вместительным (1024)
|
||||||
let (v_tx, mut v_rx) = mpsc::channel::<Bytes>(1024);
|
let (v_tx, mut v_rx) = mpsc::channel::<Bytes>(1024);
|
||||||
muxer.register_stream(stream_id, v_tx).await;
|
muxer.register_stream(stream_id, v_tx);
|
||||||
|
|
||||||
let connect_payload = target_addr.to_string();
|
let connect_payload = target_addr.to_string();
|
||||||
if muxer
|
if muxer
|
||||||
@@ -57,7 +57,7 @@ impl TcpConnection {
|
|||||||
.await
|
.await
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
muxer.remove_stream(stream_id).await;
|
muxer.remove_stream(stream_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,13 +68,13 @@ impl TcpConnection {
|
|||||||
let _ = handshake_tx.send(());
|
let _ = handshake_tx.send(());
|
||||||
} else {
|
} else {
|
||||||
netrunner_logger::warn!(stream_id, "Server rejected TCP connection");
|
netrunner_logger::warn!(stream_id, "Server rejected TCP connection");
|
||||||
muxer.remove_stream(stream_id).await;
|
muxer.remove_stream(stream_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
netrunner_logger::error!(stream_id, "Timeout waiting for proxy response");
|
netrunner_logger::error!(stream_id, "Timeout waiting for proxy response");
|
||||||
muxer.remove_stream(stream_id).await;
|
muxer.remove_stream(stream_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ impl TcpConnection {
|
|||||||
data: Bytes::new(),
|
data: Bytes::new(),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
muxer.remove_stream(stream_id).await;
|
muxer.remove_stream(stream_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ impl UdpConnection {
|
|||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
// Даем Муксеру ограниченный канал (тип Sender), чтобы компилятор пропустил
|
// Даем Муксеру ограниченный канал (тип Sender), чтобы компилятор пропустил
|
||||||
let (v_tx, mut v_rx) = mpsc::channel::<Bytes>(1024);
|
let (v_tx, mut v_rx) = mpsc::channel::<Bytes>(1024);
|
||||||
m_clone.register_stream(stream_id, v_tx).await;
|
m_clone.register_stream(stream_id, v_tx);
|
||||||
|
|
||||||
let _ = m_clone
|
let _ = m_clone
|
||||||
.send_to_netwrok(MuxMessage {
|
.send_to_netwrok(MuxMessage {
|
||||||
@@ -81,7 +81,7 @@ impl UdpConnection {
|
|||||||
data: Bytes::new(),
|
data: Bytes::new(),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
m_clone.remove_stream(stream_id).await;
|
m_clone.remove_stream(stream_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ rand = "0.10.0"
|
|||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
tokio-util = { version = "0.7", features = ["rt"] }
|
tokio-util = { version = "0.7", features = ["rt"] }
|
||||||
async-trait = "0.1.89"
|
async-trait = "0.1.89"
|
||||||
|
dashmap = "6.1.0"
|
||||||
netrunner-logger = { path = "../tools/log" }
|
netrunner-logger = { path = "../tools/log" }
|
||||||
@@ -5,6 +5,7 @@ use bytes::{Bytes, BytesMut};
|
|||||||
use netrunner_logger::{debug, error};
|
use netrunner_logger::{debug, error};
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::UdpSocket;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
pub async fn run_proxy_bridge<R, W>(
|
pub async fn run_proxy_bridge<R, W>(
|
||||||
stream_id: u32,
|
stream_id: u32,
|
||||||
mut reader: R,
|
mut reader: R,
|
||||||
@@ -58,6 +59,7 @@ pub async fn run_proxy_bridge<R, W>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Отправляем Close фрейм перед выходом
|
||||||
let _ = muxer
|
let _ = muxer
|
||||||
.send_to_netwrok(MuxMessage {
|
.send_to_netwrok(MuxMessage {
|
||||||
stream_id,
|
stream_id,
|
||||||
@@ -65,8 +67,12 @@ pub async fn run_proxy_bridge<R, W>(
|
|||||||
data: Bytes::new(),
|
data: Bytes::new(),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
// Небольшая пауза, чтобы Close фрейм успел уйти в сеть
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
|
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
|
||||||
muxer.remove_stream(stream_id).await;
|
|
||||||
|
// ИЗМЕНЕНИЕ: remove_stream теперь синхронный
|
||||||
|
muxer.remove_stream(stream_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_udp_bridge(
|
pub async fn run_udp_bridge(
|
||||||
@@ -79,7 +85,6 @@ pub async fn run_udp_bridge(
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
|
|
||||||
res = socket.recv(&mut buf) => {
|
res = socket.recv(&mut buf) => {
|
||||||
match res {
|
match res {
|
||||||
Ok(0) => break,
|
Ok(0) => break,
|
||||||
@@ -98,7 +103,6 @@ pub async fn run_udp_bridge(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
maybe_data = v_rx.recv() => {
|
maybe_data = v_rx.recv() => {
|
||||||
match maybe_data {
|
match maybe_data {
|
||||||
Some(data) => {
|
Some(data) => {
|
||||||
@@ -124,6 +128,9 @@ pub async fn run_udp_bridge(
|
|||||||
data: Bytes::new(),
|
data: Bytes::new(),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
|
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
|
||||||
muxer.remove_stream(stream_id).await;
|
|
||||||
|
// ИЗМЕНЕНИЕ: remove_stream теперь синхронный
|
||||||
|
muxer.remove_stream(stream_id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ impl TunnelHandler for ClientHandler {
|
|||||||
} => {
|
} => {
|
||||||
let stream_id = self.muxer.next_id();
|
let stream_id = self.muxer.next_id();
|
||||||
let (v_tx, mut v_rx) = mpsc::channel::<bytes::Bytes>(1024);
|
let (v_tx, mut v_rx) = mpsc::channel::<bytes::Bytes>(1024);
|
||||||
self.muxer.register_stream(stream_id, v_tx).await;
|
self.muxer.register_stream(stream_id, v_tx);
|
||||||
|
|
||||||
self.muxer
|
self.muxer
|
||||||
.send_to_netwrok(MuxMessage {
|
.send_to_netwrok(MuxMessage {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ impl StreamHandler {
|
|||||||
let muxer = self.muxer.clone();
|
let muxer = self.muxer.clone();
|
||||||
|
|
||||||
let (v_tx, v_rx) = tokio::sync::mpsc::channel(512);
|
let (v_tx, v_rx) = tokio::sync::mpsc::channel(512);
|
||||||
muxer.register_stream(stream_id, v_tx).await;
|
muxer.register_stream(stream_id, v_tx);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
@@ -96,7 +96,7 @@ impl StreamHandler {
|
|||||||
let muxer = self.muxer.clone();
|
let muxer = self.muxer.clone();
|
||||||
|
|
||||||
let (v_tx, v_rx) = tokio::sync::mpsc::channel(512);
|
let (v_tx, v_rx) = tokio::sync::mpsc::channel(512);
|
||||||
muxer.register_stream(stream_id, v_tx).await;
|
muxer.register_stream(stream_id, v_tx);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
info!(stream_id, target = %target_str, "Attempting remote UDP connection");
|
info!(stream_id, target = %target_str, "Attempting remote UDP connection");
|
||||||
@@ -142,7 +142,7 @@ impl StreamHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn send_error_reply(muxer: &Muxer, stream_id: u32, code: u8, frame_type: FrameType) {
|
async fn send_error_reply(muxer: &Muxer, stream_id: u32, code: u8, frame_type: FrameType) {
|
||||||
muxer.remove_stream(stream_id).await;
|
muxer.remove_stream(stream_id);
|
||||||
let mut reply_buf = BytesMut::with_capacity(10);
|
let mut reply_buf = BytesMut::with_capacity(10);
|
||||||
let reply = SocksReply::ConnectResult {
|
let reply = SocksReply::ConnectResult {
|
||||||
reply_code: code,
|
reply_code: code,
|
||||||
@@ -162,6 +162,6 @@ impl StreamHandler {
|
|||||||
|
|
||||||
async fn on_close(&self, stream_id: u32) {
|
async fn on_close(&self, stream_id: u32) {
|
||||||
self.muxer.dispatch_to_local(stream_id, Bytes::new()).await;
|
self.muxer.dispatch_to_local(stream_id, Bytes::new()).await;
|
||||||
self.muxer.remove_stream(stream_id).await;
|
self.muxer.remove_stream(stream_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use crate::protocol::codec::frame::FrameType;
|
use crate::protocol::codec::frame::FrameType;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use std::collections::HashMap;
|
use dashmap::DashMap; // Добавь в Cargo.toml: dashmap = "6.0"
|
||||||
use std::sync::atomic::{AtomicU32, Ordering};
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::mpsc::error::SendError;
|
use tokio::sync::mpsc::error::SendError;
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use tokio::sync::RwLock;
|
|
||||||
|
|
||||||
pub struct IdGenerator {
|
pub struct IdGenerator {
|
||||||
counter: AtomicU32,
|
counter: AtomicU32,
|
||||||
@@ -33,7 +32,7 @@ pub struct MuxMessage {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Muxer {
|
pub struct Muxer {
|
||||||
to_network: Sender<MuxMessage>,
|
to_network: Sender<MuxMessage>,
|
||||||
streams: Arc<RwLock<HashMap<u32, Sender<Bytes>>>>,
|
streams: Arc<DashMap<u32, Sender<Bytes>>>,
|
||||||
id_gen: Arc<IdGenerator>,
|
id_gen: Arc<IdGenerator>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +40,7 @@ impl Muxer {
|
|||||||
pub fn new(to_network: Sender<MuxMessage>, is_client: bool) -> Self {
|
pub fn new(to_network: Sender<MuxMessage>, is_client: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
to_network,
|
to_network,
|
||||||
streams: Arc::new(RwLock::new(HashMap::new())),
|
streams: Arc::new(DashMap::new()),
|
||||||
id_gen: Arc::new(IdGenerator::new(is_client)),
|
id_gen: Arc::new(IdGenerator::new(is_client)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,19 +53,17 @@ impl Muxer {
|
|||||||
self.to_network.send(message).await
|
self.to_network.send(message).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn register_stream(&self, stream_id: u32, tx: Sender<Bytes>) {
|
pub fn register_stream(&self, stream_id: u32, tx: Sender<Bytes>) {
|
||||||
let mut lock = self.streams.write().await;
|
self.streams.insert(stream_id, tx);
|
||||||
lock.insert(stream_id, tx);
|
|
||||||
netrunner_logger::debug!(
|
netrunner_logger::debug!(
|
||||||
stream_id,
|
stream_id,
|
||||||
total_active = lock.len(),
|
total_active = self.streams.len(),
|
||||||
"MUXER: [REGISTER] Stream added"
|
"MUXER: [REGISTER] Stream added"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_stream(&self, stream_id: u32) {
|
pub fn remove_stream(&self, stream_id: u32) {
|
||||||
let mut lock = self.streams.write().await;
|
self.streams.remove(&stream_id);
|
||||||
lock.remove(&stream_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_control(
|
pub async fn send_control(
|
||||||
@@ -86,10 +83,8 @@ impl Muxer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn dispatch_to_local(&self, stream_id: u32, data: Bytes) {
|
pub async fn dispatch_to_local(&self, stream_id: u32, data: Bytes) {
|
||||||
let tx = {
|
// DashMap позволяет получить доступ к элементу без явного RwLock
|
||||||
let lock = self.streams.read().await;
|
let tx = self.streams.get(&stream_id).map(|r| r.value().clone());
|
||||||
lock.get(&stream_id).cloned()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(tx) = tx {
|
if let Some(tx) = tx {
|
||||||
if data.is_empty() {
|
if data.is_empty() {
|
||||||
@@ -107,7 +102,7 @@ impl Muxer {
|
|||||||
stream_id,
|
stream_id,
|
||||||
"MUXER: [WARN] Local channel closed, dropping packet"
|
"MUXER: [WARN] Local channel closed, dropping packet"
|
||||||
);
|
);
|
||||||
self.remove_stream(stream_id).await;
|
self.remove_stream(stream_id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
netrunner_logger::trace!(
|
netrunner_logger::trace!(
|
||||||
|
|||||||
Reference in New Issue
Block a user