diff --git a/vnt-core/src/nat/internal_nat/icmp_nat.rs b/vnt-core/src/nat/internal_nat/icmp_nat.rs index 49dc76f..1d0fc41 100644 --- a/vnt-core/src/nat/internal_nat/icmp_nat.rs +++ b/vnt-core/src/nat/internal_nat/icmp_nat.rs @@ -60,14 +60,34 @@ async fn task( let mut map: IcmpNatMap = HashMap::new(); let mut gc_interval = tokio::time::interval(ICMP_NAT_GC_INTERVAL); loop { + // 单次收发/处理失败不能拖垮整个任务:记录日志后继续, + // 短暂休眠避免持续性错误造成空转 tokio::select! { rs = tokio_icmp_socket.recv(&mut buf1) => { - let len = rs?; - tokio_icmp_socket_recv(&buf1[..len],&inner_icmp_socket,&mut map,no_tun,&network).await?; + match rs { + Ok(len) => { + if let Err(e) = tokio_icmp_socket_recv(&buf1[..len],&inner_icmp_socket,&mut map,no_tun,&network).await { + log::warn!("icmp nat outbound error: {e:?}"); + } + } + Err(e) => { + log::warn!("icmp nat recv error: {e:?}"); + tokio::time::sleep(Duration::from_millis(100)).await; + } + } } rs = inner_icmp_socket.recv_from_to(&mut buf2) => { - let (len,src,dst) = rs?; - inner_icmp_socket_recv(&buf2[..len],src,dst,&tokio_icmp_socket,&mut map,no_tun,&network).await?; + match rs { + Ok((len,src,dst)) => { + if let Err(e) = inner_icmp_socket_recv(&buf2[..len],src,dst,&tokio_icmp_socket,&mut map,no_tun,&network).await { + log::warn!("icmp nat inbound error: {e:?}"); + } + } + Err(e) => { + log::warn!("icmp nat inner recv error: {e:?}"); + tokio::time::sleep(Duration::from_millis(100)).await; + } + } } _ = gc_interval.tick() => { evict_expired(&mut map, Instant::now(), ICMP_NAT_TIMEOUT); @@ -115,7 +135,11 @@ async fn tokio_icmp_socket_recv( return Ok(()); }; if no_tun && src == Ipv4Addr::LOCALHOST { - src = network.ip().context("not ip")?; + // 虚拟地址未就绪时丢弃该应答包,而不是让错误传播杀掉整个任务 + let Some(ip) = network.ip() else { + return Ok(()); + }; + src = ip; } inner_icmp_socket @@ -148,7 +172,8 @@ async fn inner_icmp_socket_recv( if payload.len() < 4 { return Ok(()); } - if no_tun && dst == network.ip().context("not ip")? { + // 虚拟地址未就绪(None)时跳过重写,而不是让错误传播杀掉整个任务 + if no_tun && Some(dst) == network.ip() { dst = Ipv4Addr::LOCALHOST; } diff --git a/vnt-core/src/nat/internal_nat/tcp_nat.rs b/vnt-core/src/nat/internal_nat/tcp_nat.rs index 3382985..d7c5329 100644 --- a/vnt-core/src/nat/internal_nat/tcp_nat.rs +++ b/vnt-core/src/nat/internal_nat/tcp_nat.rs @@ -31,14 +31,31 @@ async fn listen_task( network: SharedNetworkAddr, ) -> anyhow::Result<()> { loop { - let (stream, _addr) = tcp_listener.accept().await?; - let mut local_addr = stream.local_addr()?; - let peer_addr = stream.peer_addr()?; + // 单次 accept/地址查询失败不能拖垮整个监听任务: + // 记录日志后继续,短暂休眠避免持续性错误造成空转 + let (stream, _addr) = match tcp_listener.accept().await { + Ok(v) => v, + Err(e) => { + log::warn!("tcp nat accept error: {e:?}"); + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + continue; + } + }; + let (mut local_addr, peer_addr) = match (stream.local_addr(), stream.peer_addr()) { + (Ok(local_addr), Ok(peer_addr)) => (local_addr, peer_addr), + (Err(e), _) | (_, Err(e)) => { + log::warn!("tcp nat get addr error: {e:?}"); + continue; + } + }; if no_tun { let IpAddr::V4(ip) = local_addr.ip() else { continue; }; - if ip == network.ip().context("not ip")? { + // 虚拟地址未就绪(None)时跳过重写,而不是终止任务 + if let Some(net_ip) = network.ip() + && ip == net_ip + { // 无tun的情况下写入本机的则写到localhost local_addr.set_ip(IpAddr::V4(Ipv4Addr::LOCALHOST)); }