15 march works with app

This commit is contained in:
2026-03-15 23:47:15 +07:00
parent 102099e1cd
commit 7dbfaec60d
38 changed files with 659 additions and 542 deletions
+1 -1
View File
@@ -2,8 +2,8 @@ use crate::protocol::codec::frame::FrameType;
use crate::proxy::connection::connection::BUF_SIZE;
use crate::proxy::connection::muxer::{MuxMessage, Muxer};
use bytes::{Bytes, BytesMut};
use netrunner_logger::{debug, error};
use tokio::sync::mpsc;
use tracing::{debug, error};
pub async fn run_proxy_bridge<R, W>(
stream_id: u32,
mut reader: R,
+80 -83
View File
@@ -1,6 +1,6 @@
use bytes::{Bytes, BytesMut};
use tracing::{instrument, info, debug, error, trace, warn};
use std::{net::SocketAddr};
use netrunner_logger::{debug, error, info, instrument, trace, warn};
use std::net::SocketAddr;
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::{
@@ -9,6 +9,7 @@ use tokio::{
},
sync::mpsc::{self},
};
use tokio_util::sync::CancellationToken;
use crate::{
protocol::{
@@ -21,13 +22,15 @@ use crate::{
parser::parser::Parser,
},
proxy::connection::{
bridge::run_proxy_bridge, engine::TunnelEngine, handler::StreamHandler, muxer::{MuxMessage, Muxer}
bridge::run_proxy_bridge,
engine::TunnelEngine,
handler::StreamHandler,
muxer::{MuxMessage, Muxer},
},
};
pub const BUF_SIZE: usize = 16384;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ConnectionRole {
Client,
@@ -43,11 +46,7 @@ pub struct Connection {
}
impl Connection {
pub fn new(
stream: TcpStream,
addr: SocketAddr,
init: bool,
) -> Self {
pub fn new(stream: TcpStream, addr: SocketAddr, init: bool) -> Self {
let (inbound, outbound) = stream.into_split();
Self {
addr,
@@ -58,27 +57,22 @@ impl Connection {
}
}
async fn read_socks_request(&mut self) -> Result<SocksRequest, String> {
loop {
match SocksRequest::parse(&mut self.read_buf) {
Ok(Some(req)) => {
info!(client = %self.addr, request = ?req, "SOCKS request successfully parsed");
return Ok(req);
}
Ok(None) => {
trace!(client = %self.addr, buffer_len = self.read_buf.len(), "SOCKS parse: need more data");
}
}
Err(e) => {
error!(client = %self.addr, error = %e, "SOCKS protocol violation");
return Err(format!("Socks parse error: {}", e));
}
}
let n = self
.inbound
.read_buf(&mut self.read_buf)
@@ -92,49 +86,36 @@ impl Connection {
warn!(client = %self.addr, "Client closed connection prematurely during SOCKS handshake");
return Err("Client closed connection during SOCKS handshake".into());
}
trace!(client = %self.addr, read_bytes = n, "Read data from client for SOCKS handshake");
}
}
async fn send_socks_reply(&mut self, reply: SocksReply) -> Result<(), String> {
let mut buf = BytesMut::with_capacity(24);
debug!(client = %self.addr, reply = ?reply, "Sending SOCKS reply to client");
reply.write_to(&mut buf);
self.outbound
.write_all(&buf)
.await
.map_err(|e| {
error!(client = %self.addr, error = %e, "Failed to send SOCKS reply");
e.to_string()
})?;
self.outbound.write_all(&buf).await.map_err(|e| {
error!(client = %self.addr, error = %e, "Failed to send SOCKS reply");
e.to_string()
})?;
Ok(())
}
#[instrument(
name = "socks_handler",
skip(self, muxer),
fields(addr = %self.addr)
)]
pub async fn handle_socks_client(mut self, muxer: Muxer) -> Result<(), String> {
info!("Starting SOCKS multiplexed handling");
debug!("Reading SOCKS handshake request");
let _ = self.read_socks_request().await.map_err(|e| {
error!("SOCKS handshake failed: {}", e);
e
})?;
self.send_socks_reply(SocksReply::HandshakeSelect { method: 0x00 }).await?;
self.send_socks_reply(SocksReply::HandshakeSelect { method: 0x00 })
.await?;
let req = self.read_socks_request().await?;
let target = if let SocksRequest::Connect { target, .. } = req {
target
@@ -145,46 +126,61 @@ impl Connection {
let stream_id = muxer.next_id();
let target_str = target.to_string();
let (v_tx, mut v_rx) = mpsc::channel::<Bytes>(1024);
muxer.register_stream(stream_id, v_tx).await;
muxer.to_network.send(MuxMessage {
stream_id,
frame_type: FrameType::Connect,
data: Bytes::from(target_str),
}).await.map_err(|e| e.to_string())?;
muxer
.to_network
.send(MuxMessage {
stream_id,
frame_type: FrameType::Connect,
data: Bytes::from(target_str),
})
.await
.map_err(|e| e.to_string())?;
let first_payload = match tokio::time::timeout(std::time::Duration::from_secs(10), v_rx.recv()).await {
Ok(Some(data)) => data,
_ => {
error!(stream_id, "Server timeout or failed to send Connect confirmation");
self.send_socks_reply(SocksReply::ConnectResult {
reply_code: 0x01, atyp: 0x01, addr: [0, 0, 0, 0], port: 0,
}).await.ok();
return Err("Target connection failed".into());
}
};
let first_payload =
match tokio::time::timeout(std::time::Duration::from_secs(10), v_rx.recv()).await {
Ok(Some(data)) => data,
_ => {
error!(
stream_id,
"Server timeout or failed to send Connect confirmation"
);
self.send_socks_reply(SocksReply::ConnectResult {
reply_code: 0x01,
atyp: 0x01,
addr: [0, 0, 0, 0],
port: 0,
})
.await
.ok();
return Err("Target connection failed".into());
}
};
if first_payload.len() >= 2 && first_payload[1] == 0x00 {
debug!(stream_id, "Server confirmed connection, forwarding SOCKS reply to browser");
self.outbound.write_all(&first_payload).await.map_err(|e| e.to_string())?;
debug!(
stream_id,
"Server confirmed connection, forwarding SOCKS reply to browser"
);
self.outbound
.write_all(&first_payload)
.await
.map_err(|e| e.to_string())?;
} else {
self.outbound.write_all(&first_payload).await.ok();
return Err("Server rejected connection".into());
}
let Self { inbound: browser_in, outbound: browser_out, .. } = self;
let Self {
inbound: browser_in,
outbound: browser_out,
..
} = self;
let muxer_clone = muxer.clone();
tokio::spawn(async move {
run_proxy_bridge(stream_id, browser_in, browser_out, muxer_clone, v_rx).await;
@@ -193,49 +189,51 @@ impl Connection {
Ok(())
}
#[instrument(
name = "server_tunnel",
skip(self),
fields(addr = %self.addr)
)]
pub async fn handle_server_tunnel(mut self) -> Result<(), String> {
pub async fn handle_server_tunnel(mut self, token: CancellationToken) -> Result<(), String> {
info!("Acting as TLS Server, waiting for ClientHello");
let (mux_tx, mux_rx) = mpsc::channel(BUF_SIZE);
let muxer = Muxer::new(mux_tx.clone(), false);
let muxer = Muxer::new(mux_tx.clone(), false);
let server_hello_bytes = loop {
match self.codec.make_server_handshake(&mut self.read_buf) {
Ok(bytes) => {
info!("ClientHello received, sending ServerHello");
break bytes;
},
}
Err(e) if e.action == ErrorAction::Wait => {
let n = self.inbound.read_buf(&mut self.read_buf).await
let n = self
.inbound
.read_buf(&mut self.read_buf)
.await
.map_err(|err| format!("Read error: {}", err))?;
if n == 0 { return Err("Client closed connection".into()); }
if n == 0 {
return Err("Client closed connection".into());
}
}
Err(e) => return Err(format!("TLS error: {:?}", e)),
}
};
self.outbound.write_all(&server_hello_bytes).await.map_err(|e| e.to_string())?;
self.outbound
.write_all(&server_hello_bytes)
.await
.map_err(|e| e.to_string())?;
info!("TLS Tunnel established as server");
let handler = std::sync::Arc::new(StreamHandler::new(muxer.clone(), ConnectionRole::Server));
let handler =
std::sync::Arc::new(StreamHandler::new(muxer.clone(), ConnectionRole::Server));
debug!("Handover to TunnelEngine");
let engine = TunnelEngine {
inbound: self.inbound,
outbound: self.outbound,
outbound: self.outbound,
codec: self.codec,
read_buf: self.read_buf,
mux_rx,
handler
handler,
token,
};
engine.run().await.map_err(|e| {
@@ -243,5 +241,4 @@ impl Connection {
e
})
}
}
+28 -5
View File
@@ -1,15 +1,19 @@
use std::sync::Arc;
use bytes::BytesMut;
use bytes::{Bytes, BytesMut};
use netrunner_logger::{debug, error, info};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::tcp::{OwnedReadHalf, OwnedWriteHalf},
sync::mpsc::Receiver,
};
use tracing::{debug, error};
use tokio_util::sync::CancellationToken;
use crate::{
protocol::{codec::codec::Codec, errors::ErrorAction},
protocol::{
codec::{codec::Codec, frame::FrameType},
errors::ErrorAction,
},
proxy::connection::{handler::StreamHandler, muxer::MuxMessage},
};
@@ -20,6 +24,7 @@ pub struct TunnelEngine {
pub read_buf: BytesMut,
pub mux_rx: Receiver<MuxMessage>,
pub handler: Arc<StreamHandler>,
pub token: CancellationToken,
}
impl TunnelEngine {
@@ -30,18 +35,35 @@ impl TunnelEngine {
let mut read_buf = self.read_buf;
let mut mux_rx = self.mux_rx;
let handler = self.handler;
let token = self.token;
let mut heartbeat = tokio::time::interval(std::time::Duration::from_secs(15));
loop {
tokio::select! {
_ = token.cancelled() => {
info!("TunnelEngine: Shutdown signal received. Closing...");
return Ok(());
}
res = Self::process_inbound(&mut inbound, &mut codec, &mut read_buf, &handler) => {
res?
}
_ = heartbeat.tick() => {
let msg = MuxMessage { stream_id: 0, frame_type: FrameType::Heartbeat, data: Bytes::new() };
Self::handle_outbound(&mut outbound, &mut codec, msg).await?;
}
Some(msg) = mux_rx.recv() => {
Self::handle_outbound( &mut outbound, &mut codec, msg).await?;
msg_opt = mux_rx.recv() => {
if let Some(msg) = msg_opt {
Self::handle_outbound(&mut outbound, &mut codec, msg).await?;
} else {
break;
}
}
}
}
Ok(())
}
async fn process_inbound(
@@ -56,6 +78,7 @@ impl TunnelEngine {
.map_err(|e| e.to_string())?;
if n == 0 && read_buf.is_empty() {
netrunner_logger::error!("Connection closed by peer (EOF detected)");
return Err("EOF".into());
}
+1 -1
View File
@@ -1,5 +1,5 @@
use bytes::{Bytes, BytesMut};
use tracing::{debug, error, info};
use netrunner_logger::{debug, error, info};
use crate::{
protocol::codec::{
+6 -6
View File
@@ -1,11 +1,11 @@
use crate::protocol::codec::frame::FrameType;
use bytes::Bytes;
use netrunner_logger::{debug, error};
use std::collections::HashMap;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
use tokio::sync::mpsc::Sender;
use tokio::sync::RwLock;
use tracing::{debug, error};
pub struct IdGenerator {
counter: AtomicU32,
@@ -53,7 +53,7 @@ impl Muxer {
pub async fn register_stream(&self, stream_id: u32, tx: Sender<Bytes>) {
let mut lock = self.streams.write().await;
lock.insert(stream_id, tx);
tracing::debug!(
netrunner_logger::debug!(
stream_id,
total_active = lock.len(),
"MUXER: [REGISTER] Stream added"
@@ -89,9 +89,9 @@ impl Muxer {
if let Some(tx) = tx {
if data.is_empty() {
tracing::debug!(stream_id, "MUXER: [EOF] Forwarding EOF to local handler");
netrunner_logger::debug!(stream_id, "MUXER: [EOF] Forwarding EOF to local handler");
} else {
tracing::trace!(
netrunner_logger::trace!(
stream_id,
len = data.len(),
"MUXER: [DISPATCH] Sending data"
@@ -99,14 +99,14 @@ impl Muxer {
}
if let Err(_e) = tx.send(data).await {
tracing::debug!(
netrunner_logger::debug!(
stream_id,
"MUXER: [WARN] Local channel closed, dropping packet"
);
self.remove_stream(stream_id).await;
}
} else {
tracing::trace!(
netrunner_logger::trace!(
stream_id,
"MUXER: [IGNORE] Packet for already closed stream"
);