15 march works with app
This commit is contained in:
@@ -58,7 +58,7 @@ impl ChaChaCipher {
|
||||
self.encrypt_state = NonceState::new(w_iv);
|
||||
self.decrypt_state = NonceState::new(r_iv);
|
||||
|
||||
tracing::debug!("Cipher keys and IVs updated for both directions");
|
||||
netrunner_logger::debug!("Cipher keys and IVs updated for both directions");
|
||||
}
|
||||
}
|
||||
impl AeadPacker for ChaChaCipher {
|
||||
@@ -69,7 +69,7 @@ impl AeadPacker for ChaChaCipher {
|
||||
|
||||
match self.encrypt_cipher.encrypt_in_place(&nonce, &nonce, data) {
|
||||
Ok(_) => {
|
||||
tracing::trace!(
|
||||
netrunner_logger::trace!(
|
||||
counter = current_counter,
|
||||
nonce = %hex::encode(nonce),
|
||||
len = data_len,
|
||||
@@ -78,7 +78,7 @@ impl AeadPacker for ChaChaCipher {
|
||||
Ok(data.split().freeze())
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
netrunner_logger::error!(
|
||||
counter = current_counter,
|
||||
nonce = %hex::encode(nonce),
|
||||
len = data_len,
|
||||
@@ -97,7 +97,7 @@ impl AeadPacker for ChaChaCipher {
|
||||
|
||||
match self.decrypt_cipher.decrypt_in_place(&nonce, &nonce, data) {
|
||||
Ok(_) => {
|
||||
tracing::trace!(
|
||||
netrunner_logger::trace!(
|
||||
counter = current_counter,
|
||||
nonce = %hex::encode(nonce),
|
||||
len = data_len,
|
||||
@@ -111,7 +111,7 @@ impl AeadPacker for ChaChaCipher {
|
||||
} else {
|
||||
hex::encode(data.as_ref())
|
||||
};
|
||||
tracing::error!(
|
||||
netrunner_logger::error!(
|
||||
counter = current_counter,
|
||||
nonce = %hex::encode(nonce),
|
||||
len = data_len,
|
||||
|
||||
@@ -74,7 +74,7 @@ impl SessionKeys {
|
||||
) -> Result<([u8; 32], [u8; 12], [u8; 32], [u8; 12]), String> {
|
||||
self.salt.set_remote_salt(salt);
|
||||
|
||||
tracing::debug!(
|
||||
netrunner_logger::debug!(
|
||||
remote_salt = %hex::encode(&salt[..8]),
|
||||
local_salt = %hex::encode(&self.salt.get_local()[..8]),
|
||||
total_salt = %hex::encode(&self.salt.get_total()[28..36]),
|
||||
@@ -120,7 +120,7 @@ impl SessionKeys {
|
||||
|
||||
let public_key = PublicKey::from(key_bytes);
|
||||
|
||||
tracing::debug!(
|
||||
netrunner_logger::debug!(
|
||||
remote_pub = %hex::encode(&key_bytes[..4]),
|
||||
role = if is_server { "Server" } else { "Client" },
|
||||
"Key exchange successful, deriving material..."
|
||||
@@ -141,7 +141,7 @@ impl SessionKeys {
|
||||
.get_shared(public_key)
|
||||
.ok_or_else(|| "No shared secret".to_string())?;
|
||||
|
||||
tracing::debug!(
|
||||
netrunner_logger::debug!(
|
||||
shared_prefix = %hex::encode(&shared_key[..8]),
|
||||
"DH Shared secret derived"
|
||||
);
|
||||
@@ -155,7 +155,7 @@ impl SessionKeys {
|
||||
|
||||
let auth_secret = HKDF::expand_key::<32>(&hkdf, b"auth_key").map_err(|e| e.to_string())?;
|
||||
self.auth_key = auth_secret;
|
||||
tracing::info!(
|
||||
netrunner_logger::info!(
|
||||
client_key_short = %hex::encode(&c_key[..4]),
|
||||
server_key_short = %hex::encode(&s_key[..4]),
|
||||
"HKDF expansion complete"
|
||||
@@ -197,13 +197,13 @@ impl SessionKeys {
|
||||
for step in (current_step.saturating_sub(2))..=(current_step.saturating_add(2)) {
|
||||
if &Self::compute_tag(&self.auth_key, step) == received_tag {
|
||||
if step != current_step {
|
||||
tracing::debug!(expected = %current_step, matched = %step, "Auth tag valid with time offset");
|
||||
netrunner_logger::debug!(expected = %current_step, matched = %step, "Auth tag valid with time offset");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
tracing::warn!(
|
||||
netrunner_logger::warn!(
|
||||
current_step = %current_step,
|
||||
"AUTH MISMATCH: All tags rejected for current window"
|
||||
);
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
mod crypto;
|
||||
mod logger;
|
||||
pub mod protocol;
|
||||
pub mod proxy;
|
||||
mod tlseng;
|
||||
mod utils;
|
||||
|
||||
pub use logger::logger_init;
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
use tracing_log::LogTracer;
|
||||
use tracing_subscriber::{fmt, prelude::*, EnvFilter, Registry};
|
||||
|
||||
pub fn logger_init() {
|
||||
eprintln!("--- [DEBUG] logger_init start ---");
|
||||
let _ = LogTracer::init();
|
||||
|
||||
let filter_layer =
|
||||
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("trace"));
|
||||
|
||||
let registry = tracing_subscriber::registry().with(filter_layer);
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
let android_layer =
|
||||
tracing_android::layer("NETRUNNER_RUST").expect("Failed to create android layer");
|
||||
|
||||
let subscriber = registry.with(android_layer);
|
||||
if let Err(e) = subscriber.try_init() {
|
||||
eprintln!("Subscriber already set: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{
|
||||
let fmt_layer = fmt::layer()
|
||||
.with_target(true)
|
||||
.with_line_number(true)
|
||||
.with_ansi(false);
|
||||
|
||||
let subscriber = registry.with(fmt_layer);
|
||||
if let Err(e) = subscriber.try_init() {
|
||||
eprintln!("Subscriber already set: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ impl Codec {
|
||||
.session_keys
|
||||
.update_keys(client_msg.random(), client_msg.extensions(), true)
|
||||
.map_err(|e| {
|
||||
tracing::error!(error = %e, "Server failed to update keys from ClientHello");
|
||||
netrunner_logger::error!(error = %e, "Server failed to update keys from ClientHello");
|
||||
TlsError::new(
|
||||
ErrorStage::Handshake("Key Err"),
|
||||
ErrorAction::Drop,
|
||||
@@ -87,7 +87,7 @@ impl Codec {
|
||||
.session_keys
|
||||
.update_keys(mes.random(), mes.extensions(), false)
|
||||
.map_err(|e| {
|
||||
tracing::error!(error = %e, "Client failed to update keys from ServerHello");
|
||||
netrunner_logger::error!(error = %e, "Client failed to update keys from ServerHello");
|
||||
TlsError::new(
|
||||
ErrorStage::Handshake("Keys update error"),
|
||||
ErrorAction::Drop,
|
||||
@@ -116,7 +116,7 @@ impl Codec {
|
||||
let padding = Padding::generate_padding();
|
||||
|
||||
let tag = self.session_keys.generate_auth_tag();
|
||||
tracing::debug!(
|
||||
netrunner_logger::debug!(
|
||||
step = %(std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs() / 60),
|
||||
auth_key_hash = %hex::encode(&self.session_keys.auth_key[..4]),
|
||||
generated_tag = %hex::encode(&tag[..4]),
|
||||
@@ -139,7 +139,7 @@ impl Codec {
|
||||
let mut frame_bytes = frame.into_bytes(&tag);
|
||||
|
||||
let encrypted_payload = self.crypto.encrypt(&mut frame_bytes).map_err(|e| {
|
||||
tracing::error!("Encryption failed: {:?}", e);
|
||||
netrunner_logger::error!("Encryption failed: {:?}", e);
|
||||
TlsError::new(
|
||||
ErrorStage::Tls("Encryption failed"),
|
||||
ErrorAction::Drop,
|
||||
@@ -189,7 +189,7 @@ impl Codec {
|
||||
received_tag.copy_from_slice(&decrypted[..16]);
|
||||
|
||||
if !self.session_keys.verify_auth_tag(&received_tag) {
|
||||
tracing::error!(
|
||||
netrunner_logger::error!(
|
||||
expected_hash = %hex::encode(&self.session_keys.auth_key[..4]),
|
||||
received = %hex::encode(&received_tag[..4]),
|
||||
"AUTH MISMATCH: Potential replay or MITM attack. Dropping connection."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use bytes::Bytes;
|
||||
use tracing::{error, trace, warn};
|
||||
use netrunner_logger::{error, trace, warn};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ErrorAction {
|
||||
|
||||
@@ -57,7 +57,7 @@ impl Parser for Frame {
|
||||
let p_len = u16::from_be_bytes([bytes[21], bytes[22]]) as usize;
|
||||
let pad_len = u16::from_be_bytes([bytes[23], bytes[24]]) as usize;
|
||||
|
||||
tracing::debug!(
|
||||
netrunner_logger::debug!(
|
||||
"CAN_PARSE: p_len={}, pad_len={}, total_needed={}, have={}",
|
||||
p_len,
|
||||
pad_len,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use tracing::{debug, error, info};
|
||||
use netrunner_logger::{debug, error, info};
|
||||
|
||||
use crate::{
|
||||
protocol::codec::{
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
|
||||
+43
-17
@@ -8,11 +8,12 @@ use crate::{
|
||||
tlseng::profile::BrowserProfile,
|
||||
};
|
||||
use bytes::BytesMut;
|
||||
use netrunner_logger::{error, info, instrument};
|
||||
use tokio::{
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
net::{TcpListener, TcpStream},
|
||||
};
|
||||
use tracing::{error, info, instrument};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
pub struct Network {
|
||||
host: String,
|
||||
@@ -36,15 +37,14 @@ impl Network {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self), fields(role = ?self.role, port = self.port))]
|
||||
pub async fn run(&self) {
|
||||
pub async fn run(&self, token: CancellationToken) {
|
||||
let addr = format!("{}:{}", self.host, self.port);
|
||||
|
||||
match self.role {
|
||||
ConnectionRole::Client => {
|
||||
info!("Starting Client mode: Initializing persistent tunnel to proxy...");
|
||||
|
||||
let muxer = match self.initialize_client_tunnel().await {
|
||||
let muxer = match self.initialize_client_tunnel(token.clone()).await {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
error!(error = %e, "Global tunnel failed. Exit.");
|
||||
@@ -56,12 +56,20 @@ impl Network {
|
||||
info!(socks_addr = %addr, "SOCKS5 ready");
|
||||
|
||||
loop {
|
||||
if let Ok((stream, client_addr)) = listener.accept().await {
|
||||
let current_muxer = muxer.clone();
|
||||
tokio::spawn(async move {
|
||||
let connection = Connection::new(stream, client_addr, false);
|
||||
let _ = connection.handle_socks_client(current_muxer).await;
|
||||
});
|
||||
tokio::select! {
|
||||
_ = token.cancelled() => {
|
||||
info!("SOCKS listener: Shutting down...");
|
||||
break;
|
||||
}
|
||||
res = listener.accept() => {
|
||||
if let Ok((stream, client_addr)) = listener.accept().await {
|
||||
let current_muxer = muxer.clone();
|
||||
tokio::spawn(async move {
|
||||
let connection = Connection::new(stream, client_addr, false);
|
||||
let _ = connection.handle_socks_client(current_muxer).await;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,20 +81,37 @@ impl Network {
|
||||
info!(listen_addr = %addr, "Proxy Server listening for incoming tunnels");
|
||||
|
||||
loop {
|
||||
if let Ok((stream, client_addr)) = listener.accept().await {
|
||||
tokio::spawn(async move {
|
||||
let connection = Connection::new(stream, client_addr, true);
|
||||
if let Err(e) = connection.handle_server_tunnel().await {
|
||||
error!(client = %client_addr, error = %e, "Tunnel error");
|
||||
tokio::select! {
|
||||
_ = token.cancelled() => {
|
||||
info!("Server listener: Shutting down...");
|
||||
break;
|
||||
}
|
||||
res = listener.accept() => {
|
||||
match res {
|
||||
Ok((stream, client_addr)) => {
|
||||
let connection = Connection::new(stream, client_addr, true);
|
||||
let connection_token = token.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = connection.handle_server_tunnel(connection_token).await {
|
||||
error!(client = %client_addr, error = %e, "Tunnel error");
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
error!(error = %e, "Failed to accept connection");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn initialize_client_tunnel(&self) -> Result<Muxer, String> {
|
||||
pub async fn initialize_client_tunnel(
|
||||
&self,
|
||||
token: CancellationToken,
|
||||
) -> Result<Muxer, String> {
|
||||
let server_addr = self.remote_proxy_addr.as_ref().ok_or("No proxy addr")?;
|
||||
|
||||
let stream = TcpStream::connect(server_addr)
|
||||
@@ -133,6 +158,7 @@ impl Network {
|
||||
read_buf: sh_buf,
|
||||
mux_rx,
|
||||
handler,
|
||||
token,
|
||||
};
|
||||
|
||||
tokio::spawn(async move { engine.run().await });
|
||||
|
||||
@@ -62,7 +62,7 @@ impl ClientHello {
|
||||
let ext_len = self.extensions.len();
|
||||
let total_handshake_len = (buf.len() - length_pos - 3) as u32;
|
||||
|
||||
tracing::debug!(
|
||||
netrunner_logger::debug!(
|
||||
handshake_type = "ClientHello",
|
||||
body_len = total_handshake_len,
|
||||
extensions_len = ext_len,
|
||||
@@ -193,7 +193,7 @@ impl ServerHello {
|
||||
let total_handshake_len = (buf.len() - length_pos - 3) as u32;
|
||||
let ext_len = self.extensions.len();
|
||||
|
||||
tracing::debug!(
|
||||
netrunner_logger::debug!(
|
||||
handshake_type = "ServerHello",
|
||||
body_len = total_handshake_len,
|
||||
extensions_len = ext_len,
|
||||
|
||||
@@ -35,7 +35,7 @@ impl TlsRecord {
|
||||
}
|
||||
|
||||
pub fn build_application_data(payload: Bytes) -> Bytes {
|
||||
tracing::trace!(payload_len = payload.len(), "Building TlsRecord from Bytes");
|
||||
netrunner_logger::trace!(payload_len = payload.len(), "Building TlsRecord from Bytes");
|
||||
|
||||
let record = Self::new(
|
||||
ContentType::ApplicationData,
|
||||
|
||||
Reference in New Issue
Block a user