mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 10:14:35 +00:00
improve direct connector (#685)
* support ipv6 stun * show interface and public ip in cli node info * direct conn should keep trying unless already direct connected * peer should use conn with smallest latency * deprecate ipv6_listener, use -l instead
This commit is contained in:
@@ -360,7 +360,13 @@ pub(crate) fn setup_sokcet2_ext(
|
||||
|
||||
socket2_socket.set_nonblocking(true)?;
|
||||
socket2_socket.set_reuse_address(true)?;
|
||||
socket2_socket.bind(&socket2::SockAddr::from(*bind_addr))?;
|
||||
if let Err(e) = socket2_socket.bind(&socket2::SockAddr::from(*bind_addr)) {
|
||||
if bind_addr.is_ipv4() {
|
||||
return Err(e.into());
|
||||
} else {
|
||||
tracing::warn!(?e, "bind failed, do not return error for ipv6");
|
||||
}
|
||||
}
|
||||
|
||||
// #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
|
||||
// socket2_socket.set_reuse_port(true)?;
|
||||
|
||||
@@ -126,7 +126,7 @@ pub trait TunnelListener: Send {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[auto_impl::auto_impl(Box)]
|
||||
#[auto_impl::auto_impl(Box, &mut)]
|
||||
pub trait TunnelConnector: Send {
|
||||
async fn connect(&mut self) -> Result<Box<dyn Tunnel>, TunnelError>;
|
||||
fn remote_url(&self) -> url::Url;
|
||||
|
||||
@@ -150,9 +150,9 @@ impl TcpTunnelConnector {
|
||||
&mut self,
|
||||
addr: SocketAddr,
|
||||
) -> Result<Box<dyn Tunnel>, super::TunnelError> {
|
||||
tracing::info!(addr = ?self.addr, "connect tcp start");
|
||||
tracing::info!(url = ?self.addr, ?addr, "connect tcp start, bind addrs: {:?}", self.bind_addrs);
|
||||
let stream = TcpStream::connect(addr).await?;
|
||||
tracing::info!(addr = ?self.addr, "connect tcp succ");
|
||||
tracing::info!(url = ?self.addr, ?addr, "connect tcp succ");
|
||||
return get_tunnel_with_tcp_stream(stream, self.addr.clone().into());
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ impl super::TunnelConnector for TcpTunnelConnector {
|
||||
async fn connect(&mut self) -> Result<Box<dyn Tunnel>, super::TunnelError> {
|
||||
let addr =
|
||||
check_scheme_and_get_socket_addr_ext::<SocketAddr>(&self.addr, "tcp", self.ip_version)?;
|
||||
if self.bind_addrs.is_empty() || addr.is_ipv6() {
|
||||
if self.bind_addrs.is_empty() {
|
||||
self.connect_with_default_bind(addr).await
|
||||
} else {
|
||||
self.connect_with_custom_bind(addr).await
|
||||
|
||||
@@ -141,12 +141,27 @@ async fn respond_stun_packet(
|
||||
.encode_into_bytes(resp_msg.clone())
|
||||
.map_err(|e| anyhow::anyhow!("stun encode error: {:?}", e))?;
|
||||
|
||||
socket
|
||||
.send_to(&rsp_buf, addr.clone())
|
||||
.await
|
||||
.with_context(|| "send stun response error")?;
|
||||
let change_req = req_msg
|
||||
.get_attribute::<ChangeRequest>()
|
||||
.map(|r| r.ip() || r.port())
|
||||
.unwrap_or(false);
|
||||
|
||||
tracing::debug!(?addr, ?req_msg, "udp respond stun packet done");
|
||||
if !change_req {
|
||||
socket
|
||||
.send_to(&rsp_buf, addr.clone())
|
||||
.await
|
||||
.with_context(|| "send stun response error")?;
|
||||
} else {
|
||||
// send from a new udp socket
|
||||
let socket = if addr.is_ipv4() {
|
||||
UdpSocket::bind("0.0.0.0:0").await?
|
||||
} else {
|
||||
UdpSocket::bind("[::]:0").await?
|
||||
};
|
||||
socket.send_to(&rsp_buf, addr.clone()).await?;
|
||||
}
|
||||
|
||||
tracing::debug!(?addr, ?req_msg, ?change_req, "udp respond stun packet done");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user