优化tcp通道

This commit is contained in:
lubeilin
2023-12-30 21:39:53 +08:00
parent ee34f525e6
commit cbc4a7378c
2 changed files with 70 additions and 115 deletions
+67 -111
View File
@@ -8,7 +8,7 @@ use std::time::{Duration, Instant};
use std::{io, thread}; use std::{io, thread};
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
use parking_lot::RwLock; use parking_lot::{Mutex, RwLock};
use tokio::net::UdpSocket; use tokio::net::UdpSocket;
use tokio::sync::watch::{channel, Receiver, Sender}; use tokio::sync::watch::{channel, Receiver, Sender};
@@ -22,7 +22,7 @@ pub struct ContextInner {
//udp用于打洞、服务端通信(可选) //udp用于打洞、服务端通信(可选)
pub(crate) main_channel: Arc<StdUdpSocket>, pub(crate) main_channel: Arc<StdUdpSocket>,
//在udp的基础上,可以选择使用tcp和服务端通信 //在udp的基础上,可以选择使用tcp和服务端通信
pub(crate) main_tcp_channel: Option<std::sync::mpsc::SyncSender<Vec<u8>>>, pub(crate) main_tcp_channel: Option<Mutex<TcpStream>>,
pub(crate) route_table: RwLock<HashMap<Ipv4Addr, Vec<(Route, AtomicCell<Instant>)>>>, pub(crate) route_table: RwLock<HashMap<Ipv4Addr, Vec<(Route, AtomicCell<Instant>)>>>,
pub(crate) status_receiver: Receiver<Status>, pub(crate) status_receiver: Receiver<Status>,
pub(crate) status_sender: Sender<Status>, pub(crate) status_sender: Sender<Status>,
@@ -40,7 +40,7 @@ pub struct Context {
impl Context { impl Context {
pub fn new( pub fn new(
main_channel: Arc<StdUdpSocket>, main_channel: Arc<StdUdpSocket>,
main_tcp_channel: Option<std::sync::mpsc::SyncSender<Vec<u8>>>, main_tcp_channel: Option<TcpStream>,
current_device: Arc<AtomicCell<CurrentDeviceInfo>>, current_device: Arc<AtomicCell<CurrentDeviceInfo>>,
_channel_num: usize, _channel_num: usize,
first_latency: bool, first_latency: bool,
@@ -48,6 +48,7 @@ impl Context {
//当前版本只支持一个通道 //当前版本只支持一个通道
let channel_num = 1; let channel_num = 1;
let (status_sender, status_receiver) = channel(Status::Cone); let (status_sender, status_receiver) = channel(Status::Cone);
let main_tcp_channel = main_tcp_channel.map(|e| Mutex::new(e));
let inner = Arc::new(ContextInner { let inner = Arc::new(ContextInner {
main_channel, main_channel,
main_tcp_channel, main_tcp_channel,
@@ -79,7 +80,7 @@ impl Context {
); );
} }
if let Some(tcp) = &self.inner.main_tcp_channel { if let Some(tcp) = &self.inner.main_tcp_channel {
let _ = tcp.send(vec![]); tcp.lock().shutdown(Shutdown::Both)?;
} }
Ok(()) Ok(())
} }
@@ -126,14 +127,32 @@ impl Context {
} }
self.inner.main_channel.send_to(buf, addr) self.inner.main_channel.send_to(buf, addr)
} }
#[inline]
pub fn send_main_tcp(&self, buf: &[u8]) -> io::Result<usize> {
if let Some(sender) = &self.inner.main_tcp_channel {
let mut stream = sender.lock();
let mut head = [0; 4];
let len = buf.len();
head[2] = (len >> 8) as u8;
head[3] = (len & 0xFF) as u8;
stream.write_all(&head)?;
stream.write_all(buf)?;
Ok(len)
} else {
return Err(io::Error::new(io::ErrorKind::NotFound, "tcp not found"));
}
}
pub fn send_main(&self, buf: &[u8], addr: SocketAddr) -> io::Result<usize> { pub fn send_main(&self, buf: &[u8], addr: SocketAddr) -> io::Result<usize> {
if let Some(sender) = &self.inner.main_tcp_channel { if let Some(sender) = &self.inner.main_tcp_channel {
if sender.try_send(buf.to_vec()).is_ok() { let mut stream = sender.lock();
Ok(buf.len()) let mut head = [0; 4];
} else { let len = buf.len();
Err(io::Error::new(io::ErrorKind::Other, "send_main err")) head[2] = (len >> 8) as u8;
} head[3] = (len & 0xFF) as u8;
stream.write_all(&head)?;
stream.write_all(buf)?;
Ok(len)
} else { } else {
self.send_main_udp(buf, addr) self.send_main_udp(buf, addr)
} }
@@ -185,17 +204,7 @@ impl Context {
pub async fn send_by_key(&self, buf: &[u8], route_key: &RouteKey) -> io::Result<usize> { pub async fn send_by_key(&self, buf: &[u8], route_key: &RouteKey) -> io::Result<usize> {
match route_key.index { match route_key.index {
TCP_ID => { TCP_ID => self.send_main_tcp(buf),
if let Some(sender) = &self.inner.main_tcp_channel {
if sender.send(buf.to_vec()).is_ok() {
Ok(buf.len())
} else {
Err(io::Error::new(io::ErrorKind::Other, "send_by_key err"))
}
} else {
Err(io::Error::new(io::ErrorKind::Other, "send_by_key err"))
}
}
UDP_ID => self.send_main_udp(buf, route_key.addr), UDP_ID => self.send_main_udp(buf, route_key.addr),
_ => { _ => {
if let Some(udp) = self.get_udp_by_route(route_key) { if let Some(udp) = self.get_udp_by_route(route_key) {
@@ -207,17 +216,7 @@ impl Context {
} }
pub fn try_send_by_key(&self, buf: &[u8], route_key: &RouteKey) -> io::Result<usize> { pub fn try_send_by_key(&self, buf: &[u8], route_key: &RouteKey) -> io::Result<usize> {
match route_key.index { match route_key.index {
TCP_ID => { TCP_ID => self.send_main_tcp(buf),
if let Some(sender) = &self.inner.main_tcp_channel {
if sender.try_send(buf.to_vec()).is_ok() {
Ok(buf.len())
} else {
Err(io::Error::new(io::ErrorKind::Other, "send_by_key err"))
}
} else {
Err(io::Error::new(io::ErrorKind::Other, "send_by_key err"))
}
}
UDP_ID => self.send_main_udp(buf, route_key.addr), UDP_ID => self.send_main_udp(buf, route_key.addr),
_ => { _ => {
if let Some(udp) = self.get_udp_by_route(route_key) { if let Some(udp) = self.get_udp_by_route(route_key) {
@@ -406,14 +405,17 @@ fn buf_channel_group(size: usize) -> (BufSenderGroup, BufReceiverGroup) {
impl Channel { impl Channel {
fn tcp_handle( fn tcp_handle(
tcp_r: &mut TcpStream, tcp_r: &mut TcpStream,
context: Context, context: &Context,
handler: ChannelDataHandler, handler: &ChannelDataHandler,
head_reserve: usize, head_reserve: usize,
) -> io::Result<()> { ) -> io::Result<()> {
let mut head = [0; 4]; let mut head = [0; 4];
let addr = tcp_r.peer_addr()?; let addr = tcp_r.peer_addr()?;
let key = RouteKey::new(TCP_ID, addr); let key = RouteKey::new(TCP_ID, addr);
loop { loop {
if context.is_close() {
return Ok(());
}
let mut buf = [0; 4096]; let mut buf = [0; 4096];
tcp_r.read_exact(&mut head)?; tcp_r.read_exact(&mut head)?;
let len = (((head[2] as u16) << 8) | head[3] as u16) as usize; let len = (((head[2] as u16) << 8) | head[3] as u16) as usize;
@@ -424,97 +426,57 @@ impl Channel {
)); ));
} }
tcp_r.read_exact(&mut buf[head_reserve..head_reserve + len])?; tcp_r.read_exact(&mut buf[head_reserve..head_reserve + len])?;
handler.handle(&mut buf, head_reserve, head_reserve + len, key, &context); handler.handle(&mut buf, head_reserve, head_reserve + len, key, context);
} }
} }
fn start_tcp( fn start_tcp(
worker: VntWorker,
mut tcp_stream: TcpStream, mut tcp_stream: TcpStream,
receiver: std::sync::mpsc::Receiver<Vec<u8>>,
context: Context, context: Context,
handler: ChannelDataHandler, handler: ChannelDataHandler,
head_reserve: usize, head_reserve: usize,
) { ) {
let current_device = context.inner.current_device.clone(); let current_device = context.inner.current_device.clone();
{
let mut tcp_r = tcp_stream.try_clone().unwrap();
let context = context.clone();
let handler = handler.clone();
thread::Builder::new()
.name("tcp_reader".into())
.spawn(move || {
if let Err(e) = Self::tcp_handle(&mut tcp_r, context, handler, head_reserve) {
log::info!("tcp链接断开:{:?}", e);
}
if let Err(e) = tcp_r.shutdown(Shutdown::Both) {
log::info!("tcp链接关闭异常:{:?}", e);
}
})
.unwrap();
}
let mut head = [0; 4];
loop { loop {
let data = match receiver.recv() { if let Err(e) = tcp_stream.set_nodelay(true) {
Ok(data) => data, log::info!("set_nodelay:{:?}", e);
Err(_) => {
break;
}
};
let len = data.len();
if len == 0 {
break;
} }
head[2] = (len >> 8) as u8; if let Err(e) = tcp_stream.set_write_timeout(Some(Duration::from_secs(3))) {
head[3] = (len & 0xFF) as u8; log::info!("set_write_timeout:{:?}", e);
let mut err = false;
if let Err(e) = tcp_stream.write_all(&head) {
err = true;
log::info!("发送失败,需要重连:{:?}", e);
} else if let Err(e) = tcp_stream.write_all(&data) {
err = true;
log::info!("发送失败,需要重连:{:?}", e);
} }
if err { if let Err(e) = tcp_stream.set_read_timeout(Some(Duration::from_secs(10))) {
if let Err(e) = tcp_stream.shutdown(Shutdown::Both) { log::info!("set_read_timeout:{:?}", e);
log::info!("tcp链接关闭异常:{:?}", e); }
if let Err(e) = Self::tcp_handle(&mut tcp_stream, &context, &handler, head_reserve) {
log::info!("tcp链接断开:{:?}", e);
}
if let Err(e) = tcp_stream.shutdown(Shutdown::Both) {
log::info!("tcp链接关闭异常:{:?}", e);
}
loop {
if context.is_close() {
return;
} }
match TcpStream::connect(current_device.load().connect_server) { let device_info = current_device.load();
match TcpStream::connect(device_info.connect_server) {
Ok(tcp) => { Ok(tcp) => {
tcp.set_read_timeout(Some(Duration::from_secs(10))).unwrap(); tcp_stream = tcp.try_clone().unwrap();
tcp_stream = tcp; let mut guard = context.inner.main_tcp_channel.as_ref().unwrap().lock();
let mut tcp_r = tcp_stream.try_clone().unwrap(); *guard = tcp;
let context = context.clone(); break;
let handler = handler.clone();
thread::Builder::new()
.name("tcp_reader".into())
.spawn(move || {
if let Err(e) =
Self::tcp_handle(&mut tcp_r, context, handler, head_reserve)
{
log::info!("重连后 tcp链接断开:{:?}", e);
}
if let Err(e) = tcp_r.shutdown(Shutdown::Both) {
log::info!("重连后 tcp链接关闭异常:{:?}", e);
}
})
.unwrap();
} }
Err(e) => { Err(e) => {
log::info!("重连失败:{:?}", e); log::info!("重连失败,{},{:?}", device_info.connect_server, e);
thread::sleep(Duration::from_secs(3));
} }
} }
} }
} }
if let Err(e) = tcp_stream.shutdown(Shutdown::Both) {
log::info!("tcp链接关闭异常:{:?}", e);
}
worker.stop_all();
} }
pub async fn start( pub async fn start(
self, self,
mut worker: VntWorker, mut worker: VntWorker,
tcp: Option<(TcpStream, std::sync::mpsc::Receiver<Vec<u8>>)>, tcp: Option<TcpStream>,
head_reserve: usize, //头部预留字节 head_reserve: usize, //头部预留字节
symmetric_channel_num: usize, //对称网络,则再加一组监听,提升打洞成功率 symmetric_channel_num: usize, //对称网络,则再加一组监听,提升打洞成功率
relay: bool, relay: bool,
@@ -544,32 +506,26 @@ impl Channel {
} else { } else {
None None
}; };
if let Some((tcp_stream, receiver)) = tcp { if let Some(tcp_stream) = tcp {
let context = context.clone(); let context = context.clone();
let handler = handler.clone(); let handler = handler.clone();
let main_channel_tcp = worker.worker("main_channel_tcp"); let main_channel_tcp = worker.worker("main_channel_tcp");
thread::Builder::new() thread::Builder::new()
.name("main_channel_tcp".into()) .name("channel_tcp".into())
.spawn(move || { .spawn(move || {
Self::start_tcp( Self::start_tcp(tcp_stream, context, handler, head_reserve);
main_channel_tcp, drop(main_channel_tcp)
tcp_stream,
receiver,
context,
handler,
head_reserve,
)
}) })
.unwrap(); .unwrap();
} }
{ {
let worker = worker.worker("main_channel_1"); let worker = worker.worker("main_channel_udp");
let context = context.clone(); let context = context.clone();
let main_channel = main_channel.clone(); let main_channel = main_channel.clone();
let handler = handler.clone(); let handler = handler.clone();
let buf_sender = buf_sender.clone(); let buf_sender = buf_sender.clone();
thread::Builder::new() thread::Builder::new()
.name("ipv4-recv".into()) .name("channel_udp".into())
.spawn(move || { .spawn(move || {
log::info!("启动udp v4"); log::info!("启动udp v4");
Self::main_start_( Self::main_start_(
+3 -4
View File
@@ -236,9 +236,8 @@ impl VntUtil {
let (cone_sender, cone_receiver) = channel(3); let (cone_sender, cone_receiver) = channel(3);
let (symmetric_sender, symmetric_receiver) = channel(2); let (symmetric_sender, symmetric_receiver) = channel(2);
let (tcp_sender, tcp) = if let Some(main_tcp_channel) = self.main_tcp_channel { let (tcp_sender, tcp_receiver) = if let Some(main_tcp_channel) = self.main_tcp_channel {
let (tcp_sender, tcp_receiver) = std::sync::mpsc::sync_channel::<Vec<u8>>(100); (Some(main_tcp_channel.try_clone()?), Some(main_tcp_channel))
(Some(tcp_sender), Some((main_tcp_channel, tcp_receiver)))
} else { } else {
(None, None) (None, None)
}; };
@@ -383,7 +382,7 @@ impl VntUtil {
let relay = config.relay; let relay = config.relay;
tokio::spawn(async move { tokio::spawn(async move {
channel channel
.start(channel_worker, tcp, 14, 65, relay, config.parallel) .start(channel_worker, tcp_receiver, 14, 65, relay, config.parallel)
.await .await
}); });
} }