[mio] 修复重连问题

This commit is contained in:
lubeilin
2024-03-11 21:59:13 +08:00
parent c63813e590
commit e78994ceb4
8 changed files with 84 additions and 52 deletions
+5 -24
View File
@@ -156,33 +156,14 @@ impl ContextInner {
pub fn change_status( pub fn change_status(
&self, &self,
current_device: &AtomicCell<CurrentDeviceInfo>, current_device: &AtomicCell<CurrentDeviceInfo>,
connect_status: ConnectStatus,
) -> CurrentDeviceInfo { ) -> CurrentDeviceInfo {
let mut cur = current_device.load();
loop { loop {
let status = if self.route_table.route_one(&cur.virtual_gateway).is_some() { let cur = current_device.load();
//已连接
if cur.status.online() {
return cur;
}
//状态变为已连接
ConnectStatus::Connected
} else {
//未连接
if cur.status.offline() {
return cur;
}
//状态变为未连接
ConnectStatus::Connecting
};
let mut new_info = cur; let mut new_info = cur;
new_info.status = status; new_info.status = connect_status;
match current_device.compare_exchange(cur, new_info) { if current_device.compare_exchange(cur, new_info).is_ok() {
Ok(_) => { return new_info;
return new_info;
}
Err(c) => {
cur = c;
}
} }
} }
} }
+4
View File
@@ -19,6 +19,7 @@ use crate::cipher::Cipher;
use crate::cipher::RsaCipher; use crate::cipher::RsaCipher;
use crate::core::Config; use crate::core::Config;
use crate::external_route::{AllowExternalRoute, ExternalRoute}; use crate::external_route::{AllowExternalRoute, ExternalRoute};
use crate::handle::handshaker::Handshake;
use crate::handle::maintain::PunchReceiver; use crate::handle::maintain::PunchReceiver;
use crate::handle::recv_data::RecvDataHandler; use crate::handle::recv_data::RecvDataHandler;
use crate::handle::{ use crate::handle::{
@@ -143,6 +144,7 @@ impl Vnt {
let down_counter = let down_counter =
U64Adder::with_capacity(config.ports.as_ref().map(|v| v.len()).unwrap_or_default() + 8); U64Adder::with_capacity(config.ports.as_ref().map(|v| v.len()).unwrap_or_default() + 8);
let down_count_watcher = down_counter.watch(); let down_count_watcher = down_counter.watch();
let handshake = Handshake::new();
let handler = RecvDataHandler::new( let handler = RecvDataHandler::new(
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
rsa_cipher, rsa_cipher,
@@ -161,6 +163,7 @@ impl Vnt {
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
proxy_map.clone(), proxy_map.clone(),
down_counter, down_counter,
handshake.clone(),
); );
//初始化网络数据通道 //初始化网络数据通道
@@ -196,6 +199,7 @@ impl Vnt {
tcp_socket_sender.clone(), tcp_socket_sender.clone(),
callback.clone(), callback.clone(),
0, 0,
handshake,
); );
{ {
let context = context.clone(); let context = context.clone();
+28
View File
@@ -1,7 +1,12 @@
use std::io; use std::io;
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::{Duration, Instant};
use crossbeam_utils::atomic::AtomicCell;
use protobuf::Message; use protobuf::Message;
use crate::channel::context::Context;
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
use crate::cipher::RsaCipher; use crate::cipher::RsaCipher;
use crate::handle::{GATEWAY_IP, SELF_IP}; use crate::handle::{GATEWAY_IP, SELF_IP};
@@ -19,6 +24,29 @@ pub enum HandshakeEnum {
ServerError(String), ServerError(String),
Other(String), Other(String),
} }
#[derive(Clone)]
pub struct Handshake {
time: Arc<AtomicCell<Instant>>,
}
impl Handshake {
pub fn new() -> Self {
Handshake {
time: Arc::new(AtomicCell::new(Instant::now() - Duration::from_secs(60))),
}
}
pub fn send(&self, context: &Context, secret: bool, addr: SocketAddr) -> io::Result<()> {
let last = self.time.load();
//短时间不重复发送
if last.elapsed() < Duration::from_secs(2) {
return Ok(());
}
let request_packet = handshake_request_packet(secret)?;
log::info!("发送握手请求,secret={},{:?}", secret, addr);
context.send_default(request_packet.buffer(), addr)?;
self.time.store(Instant::now());
Ok(())
}
}
/// 第一次握手数据 /// 第一次握手数据
pub fn handshake_request_packet(secret: bool) -> io::Result<NetPacket<Vec<u8>>> { pub fn handshake_request_packet(secret: bool) -> io::Result<NetPacket<Vec<u8>>> {
+7
View File
@@ -102,6 +102,9 @@ fn heartbeat0(
if current_device.is_gateway(&peer.virtual_ip) { if current_device.is_gateway(&peer.virtual_ip) {
continue; continue;
} }
if current_device.status.offline() {
continue;
}
if context.route_table.route_one(&peer.virtual_ip).is_none() { if context.route_table.route_one(&peer.virtual_ip).is_none() {
//路由为空,则向服务端地址发送 //路由为空,则向服务端地址发送
let net_packet = match heartbeat_packet_client(client_cipher, src_ip, peer.virtual_ip) { let net_packet = match heartbeat_packet_client(client_cipher, src_ip, peer.virtual_ip) {
@@ -165,6 +168,10 @@ fn client_relay0(
device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>, device_list: &Mutex<(u16, Vec<PeerDeviceInfo>)>,
client_cipher: &Cipher, client_cipher: &Cipher,
) -> io::Result<()> { ) -> io::Result<()> {
// 离线了不再探测
if current_device.status.offline() {
return Ok(());
}
let peer_list = { device_list.lock().1.clone() }; let peer_list = { device_list.lock().1.clone() };
let mut routes = context.route_table.route_table_p2p(); let mut routes = context.route_table.route_table_p2p();
for peer in &peer_list { for peer in &peer_list {
+13 -11
View File
@@ -2,7 +2,8 @@ use crate::channel::context::Context;
use crate::channel::idle::{Idle, IdleType}; use crate::channel::idle::{Idle, IdleType};
use crate::channel::sender::AcceptSocketSender; use crate::channel::sender::AcceptSocketSender;
use crate::handle::callback::{ConnectInfo, ErrorType}; use crate::handle::callback::{ConnectInfo, ErrorType};
use crate::handle::{handshaker, BaseConfigInfo, CurrentDeviceInfo}; use crate::handle::handshaker::Handshake;
use crate::handle::{handshaker, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo};
use crate::util::Scheduler; use crate::util::Scheduler;
use crate::{ErrorInfo, VntCallback}; use crate::{ErrorInfo, VntCallback};
use crossbeam_utils::atomic::AtomicCell; use crossbeam_utils::atomic::AtomicCell;
@@ -35,6 +36,7 @@ pub fn idle_gateway<Call: VntCallback>(
tcp_socket_sender: AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>, tcp_socket_sender: AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
call: Call, call: Call,
mut connect_count: usize, mut connect_count: usize,
handshake: Handshake,
) { ) {
idle_gateway0( idle_gateway0(
&context, &context,
@@ -43,6 +45,7 @@ pub fn idle_gateway<Call: VntCallback>(
&tcp_socket_sender, &tcp_socket_sender,
&call, &call,
&mut connect_count, &mut connect_count,
&handshake,
); );
let rs = scheduler.timeout(Duration::from_secs(5), move |s| { let rs = scheduler.timeout(Duration::from_secs(5), move |s| {
idle_gateway( idle_gateway(
@@ -53,6 +56,7 @@ pub fn idle_gateway<Call: VntCallback>(
tcp_socket_sender, tcp_socket_sender,
call, call,
connect_count, connect_count,
handshake,
) )
}); });
if !rs { if !rs {
@@ -66,6 +70,7 @@ fn idle_gateway0<Call: VntCallback>(
tcp_socket_sender: &AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>, tcp_socket_sender: &AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
call: &Call, call: &Call,
connect_count: &mut usize, connect_count: &mut usize,
handshake: &Handshake,
) { ) {
if let Err(e) = check_gateway_channel( if let Err(e) = check_gateway_channel(
context, context,
@@ -74,6 +79,7 @@ fn idle_gateway0<Call: VntCallback>(
tcp_socket_sender, tcp_socket_sender,
call, call,
connect_count, connect_count,
handshake,
) { ) {
let cur = current_device.load(); let cur = current_device.load();
call.error(ErrorInfo::new_msg( call.error(ErrorInfo::new_msg(
@@ -96,10 +102,8 @@ fn idle_route0<Call: VntCallback>(
context.remove_route(&ip, route.route_key()); context.remove_route(&ip, route.route_key());
if cur.is_gateway(&ip) { if cur.is_gateway(&ip) {
//网关路由过期,则需要改变状态 //网关路由过期,则需要改变状态
let cur = context.change_status(current_device); context.change_status(current_device, ConnectStatus::Connecting);
if cur.status.offline() { call.error(ErrorInfo::new(ErrorType::Disconnect));
call.error(ErrorInfo::new(ErrorType::Disconnect));
}
} }
Duration::from_millis(100) Duration::from_millis(100)
} }
@@ -115,21 +119,19 @@ fn check_gateway_channel<Call: VntCallback>(
tcp_socket_sender: &AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>, tcp_socket_sender: &AcceptSocketSender<(TcpStream, SocketAddr, Option<Vec<u8>>)>,
call: &Call, call: &Call,
count: &mut usize, count: &mut usize,
handshake: &Handshake,
) -> io::Result<()> { ) -> io::Result<()> {
let current_device = context.change_status(current_device); let current_device = current_device.load();
if current_device.status.offline() { if current_device.status.offline() {
*count += 1; *count += 1;
if *count % 4 == 0 {
context.change_main_index();
}
//需要重连 //需要重连
call.connect(ConnectInfo::new(*count, current_device.connect_server)); call.connect(ConnectInfo::new(*count, current_device.connect_server));
let request_packet = handshaker::handshake_request_packet(config.client_secret)?;
log::info!("发送握手请求,{:?}", config); log::info!("发送握手请求,{:?}", config);
if let Err(e) = context.send_default(request_packet.buffer(), current_device.connect_server) if let Err(e) = handshake.send(context, config.client_secret, current_device.connect_server)
{ {
log::warn!("{:?}", e); log::warn!("{:?}", e);
if context.is_main_tcp() { if context.is_main_tcp() {
let request_packet = handshaker::handshake_request_packet(config.client_secret)?;
//tcp需要重连 //tcp需要重连
let tcp_stream = std::net::TcpStream::connect_timeout( let tcp_stream = std::net::TcpStream::connect_timeout(
&current_device.connect_server, &current_device.connect_server,
+11 -13
View File
@@ -123,17 +123,16 @@ fn punch_request(
client_cipher: Cipher, client_cipher: Cipher,
count: usize, count: usize,
) { ) {
if let Err(e) = punch0( let curr = current_device.load();
&context, let secs = if curr.status.online() {
&nat_test, if let Err(e) = punch0(&context, &nat_test, &device_list, curr, &client_cipher) {
&device_list, log::warn!("{:?}", e)
&current_device, }
&client_cipher, let sleep_time = [3, 5, 7, 11, 13, 17, 19, 23, 29];
) { Duration::from_secs(sleep_time[count % sleep_time.len()])
log::warn!("{:?}", e) } else {
} Duration::from_secs(3)
let sleep_time = [3, 5, 7, 11, 13, 17, 19, 23, 29]; };
let secs = Duration::from_secs(sleep_time[count % sleep_time.len()]);
let rs = scheduler.timeout(secs, move |s| { let rs = scheduler.timeout(secs, move |s| {
punch_request( punch_request(
s, s,
@@ -155,10 +154,9 @@ fn punch0(
context: &Context, context: &Context,
nat_test: &NatTest, nat_test: &NatTest,
device_list: &Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>, device_list: &Arc<Mutex<(u16, Vec<PeerDeviceInfo>)>>,
current_device: &Arc<AtomicCell<CurrentDeviceInfo>>, current_device: CurrentDeviceInfo,
client_cipher: &Cipher, client_cipher: &Cipher,
) -> io::Result<()> { ) -> io::Result<()> {
let current_device = current_device.load();
let nat_info = nat_test.nat_info(); let nat_info = nat_test.nat_info();
let current_ip = current_device.virtual_ip; let current_ip = current_device.virtual_ip;
let mut list: Vec<PeerDeviceInfo> = device_list let mut list: Vec<PeerDeviceInfo> = device_list
+3
View File
@@ -17,6 +17,7 @@ use crate::cipher::Cipher;
use crate::cipher::RsaCipher; use crate::cipher::RsaCipher;
use crate::external_route::{AllowExternalRoute, ExternalRoute}; use crate::external_route::{AllowExternalRoute, ExternalRoute};
use crate::handle::callback::VntCallback; use crate::handle::callback::VntCallback;
use crate::handle::handshaker::Handshake;
use crate::handle::maintain::PunchSender; use crate::handle::maintain::PunchSender;
use crate::handle::recv_data::client::ClientPacketHandler; use crate::handle::recv_data::client::ClientPacketHandler;
use crate::handle::recv_data::server::ServerPacketHandler; use crate::handle::recv_data::server::ServerPacketHandler;
@@ -66,6 +67,7 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
route: AllowExternalRoute, route: AllowExternalRoute,
#[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>, #[cfg(feature = "ip_proxy")] ip_proxy_map: Option<IpProxyMap>,
counter: U64Adder, counter: U64Adder,
handshake: Handshake,
) -> Self { ) -> Self {
let server = ServerPacketHandler::new( let server = ServerPacketHandler::new(
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
@@ -78,6 +80,7 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
nat_test.clone(), nat_test.clone(),
callback, callback,
external_route, external_route,
handshake,
); );
let client = ClientPacketHandler::new( let client = ClientPacketHandler::new(
device.clone(), device.clone(),
+13 -4
View File
@@ -23,8 +23,11 @@ use crate::external_route::ExternalRoute;
use crate::handle::callback::{ErrorInfo, ErrorType, HandshakeInfo, RegisterInfo, VntCallback}; use crate::handle::callback::{ErrorInfo, ErrorType, HandshakeInfo, RegisterInfo, VntCallback};
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
use crate::handle::handshaker; use crate::handle::handshaker;
use crate::handle::handshaker::Handshake;
use crate::handle::recv_data::PacketHandler; use crate::handle::recv_data::PacketHandler;
use crate::handle::{registrar, BaseConfigInfo, CurrentDeviceInfo, PeerDeviceInfo, GATEWAY_IP}; use crate::handle::{
registrar, BaseConfigInfo, ConnectStatus, CurrentDeviceInfo, PeerDeviceInfo, GATEWAY_IP,
};
use crate::nat::NatTest; use crate::nat::NatTest;
use crate::proto; use crate::proto;
use crate::proto::message::{DeviceList, HandshakeResponse, RegistrationResponse}; use crate::proto::message::{DeviceList, HandshakeResponse, RegistrationResponse};
@@ -49,6 +52,7 @@ pub struct ServerPacketHandler<Call> {
up_key_time: Arc<AtomicCell<Instant>>, up_key_time: Arc<AtomicCell<Instant>>,
route_record: Arc<Mutex<Vec<(Ipv4Addr, Ipv4Addr)>>>, route_record: Arc<Mutex<Vec<(Ipv4Addr, Ipv4Addr)>>>,
external_route: ExternalRoute, external_route: ExternalRoute,
handshake: Handshake,
} }
impl<Call> ServerPacketHandler<Call> { impl<Call> ServerPacketHandler<Call> {
@@ -62,6 +66,7 @@ impl<Call> ServerPacketHandler<Call> {
nat_test: NatTest, nat_test: NatTest,
callback: Call, callback: Call,
external_route: ExternalRoute, external_route: ExternalRoute,
handshake: Handshake,
) -> Self { ) -> Self {
Self { Self {
#[cfg(feature = "server_encrypt")] #[cfg(feature = "server_encrypt")]
@@ -77,6 +82,7 @@ impl<Call> ServerPacketHandler<Call> {
up_key_time: Arc::new(AtomicCell::new(Instant::now() - Duration::from_secs(60))), up_key_time: Arc::new(AtomicCell::new(Instant::now() - Duration::from_secs(60))),
route_record: Arc::new(Mutex::default()), route_record: Arc::new(Mutex::default()),
external_route, external_route,
handshake,
} }
} }
} }
@@ -239,6 +245,7 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
new_current_device.virtual_ip = virtual_ip; new_current_device.virtual_ip = virtual_ip;
new_current_device.virtual_netmask = virtual_netmask; new_current_device.virtual_netmask = virtual_netmask;
new_current_device.virtual_gateway = virtual_gateway; new_current_device.virtual_gateway = virtual_gateway;
new_current_device.status = crate::handle::ConnectStatus::Connected;
if let Err(c) = self if let Err(c) = self
.current_device .current_device
.compare_exchange(cur, new_current_device) .compare_exchange(cur, new_current_device)
@@ -248,7 +255,6 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
break; break;
} }
} }
let _ = context.change_status(&self.current_device);
let public_ip = response.public_ip.into(); let public_ip = response.public_ip.into();
let public_port = response.public_port as u16; let public_port = response.public_port as u16;
@@ -380,10 +386,10 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
} }
fn error( fn error(
&self, &self,
_context: &Context, context: &Context,
_current_device: &CurrentDeviceInfo, _current_device: &CurrentDeviceInfo,
net_packet: NetPacket<&mut [u8]>, net_packet: NetPacket<&mut [u8]>,
_route_key: RouteKey, route_key: RouteKey,
) -> io::Result<()> { ) -> io::Result<()> {
match InErrorPacket::new(net_packet.transport_protocol(), net_packet.payload())? { match InErrorPacket::new(net_packet.transport_protocol(), net_packet.payload())? {
InErrorPacket::TokenError => { InErrorPacket::TokenError => {
@@ -392,6 +398,7 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
self.callback.error(err); self.callback.error(err);
} }
InErrorPacket::Disconnect => { InErrorPacket::Disconnect => {
context.change_status(&self.current_device, ConnectStatus::Connecting);
let err = ErrorInfo::new(ErrorType::Disconnect); let err = ErrorInfo::new(ErrorType::Disconnect);
self.callback.error(err); self.callback.error(err);
//掉线epoch要归零 //掉线epoch要归零
@@ -400,6 +407,8 @@ impl<Call: VntCallback> ServerPacketHandler<Call> {
dev.0 = 0; dev.0 = 0;
drop(dev); drop(dev);
} }
self.handshake
.send(context, self.config_info.client_secret, route_key.addr)?;
// self.register(current_device, context, route_key)?; // self.register(current_device, context, route_key)?;
} }
InErrorPacket::AddressExhausted => { InErrorPacket::AddressExhausted => {