diff --git a/easytier/src/common/stun.rs b/easytier/src/common/stun.rs index 6527d13..a296b6d 100644 --- a/easytier/src/common/stun.rs +++ b/easytier/src/common/stun.rs @@ -87,7 +87,7 @@ impl Stun { pub fn new(stun_server: SocketAddr) -> Self { Self { stun_server, - req_repeat: 1, + req_repeat: 2, resp_timeout: Duration::from_millis(3000), } } @@ -432,9 +432,9 @@ impl StunInfoCollector { // stun server cross nation may return a external ip address with high latency and loss rate vec![ "stun.miwifi.com:3478".to_string(), - "stun.qq.com:3478".to_string(), - // "stun.chat.bilibili.com:3478".to_string(), // bilibili's stun server doesn't repond to change_ip and change_port - "fwa.lifesizecloud.com:3478".to_string(), + "stun.chat.bilibili.com:3478".to_string(), // bilibili's stun server doesn't repond to change_ip and change_port + "stun.cloudflare.com:3478".to_string(), + "stun.syncthing.net:3478".to_string(), "stun.isp.net.au:3478".to_string(), "stun.nextcloud.com:3478".to_string(), "stun.freeswitch.org:3478".to_string(), @@ -444,9 +444,6 @@ impl StunInfoCollector { "stun.radiojar.com:3478".to_string(), "stun.sonetel.com:3478".to_string(), "stun.voipgate.com:3478".to_string(), - "stun.counterpath.com:3478".to_string(), - "180.235.108.91:3478".to_string(), - "193.22.2.248:3478".to_string(), ] } diff --git a/easytier/src/tunnel/common.rs b/easytier/src/tunnel/common.rs index cfefc25..04d170a 100644 --- a/easytier/src/tunnel/common.rs +++ b/easytier/src/tunnel/common.rs @@ -341,6 +341,10 @@ pub(crate) fn setup_sokcet2_ext( crate::arch::windows::setup_socket_for_win(socket2_socket, bind_addr, bind_dev, is_udp)?; } + if bind_addr.is_ipv6() { + socket2_socket.set_only_v6(true)?; + } + socket2_socket.set_nonblocking(true)?; socket2_socket.set_reuse_address(true)?; socket2_socket.bind(&socket2::SockAddr::from(*bind_addr))?; @@ -472,6 +476,7 @@ pub mod tests { let lis = tokio::spawn(async move { let ret = listener.accept().await.unwrap(); + println!("accept: {:?}", ret.info()); assert_eq!( ret.info().unwrap().local_addr, listener.local_url().to_string() @@ -480,6 +485,7 @@ pub mod tests { }); let tunnel = c_netns.run_async(|| connector.connect()).await.unwrap(); + println!("connect: {:?}", tunnel.info()); assert_eq!( tunnel.info().unwrap().remote_addr, diff --git a/easytier/src/tunnel/mod.rs b/easytier/src/tunnel/mod.rs index 2a7b1bc..454b654 100644 --- a/easytier/src/tunnel/mod.rs +++ b/easytier/src/tunnel/mod.rs @@ -118,7 +118,14 @@ pub trait TunnelConnector: Send { } pub fn build_url_from_socket_addr(addr: &String, scheme: &str) -> url::Url { - url::Url::parse(format!("{}://{}", scheme, addr).as_str()).unwrap() + if let Ok(sock_addr) = addr.parse::() { + let mut ret_url = url::Url::parse(format!("{}://0.0.0.0", scheme).as_str()).unwrap(); + ret_url.set_ip_host(sock_addr.ip()).unwrap(); + ret_url.set_port(Some(sock_addr.port())).unwrap(); + ret_url + } else { + url::Url::parse(format!("{}://{}", scheme, addr).as_str()).unwrap() + } } impl std::fmt::Debug for dyn Tunnel { diff --git a/easytier/src/tunnel/tcp.rs b/easytier/src/tunnel/tcp.rs index 0b334d6..60cc6b6 100644 --- a/easytier/src/tunnel/tcp.rs +++ b/easytier/src/tunnel/tcp.rs @@ -34,16 +34,13 @@ impl TunnelListener for TcpTunnelListener { async fn listen(&mut self) -> Result<(), TunnelError> { let addr = check_scheme_and_get_socket_addr::(&self.addr, "tcp")?; - let socket = if addr.is_ipv4() { - TcpSocket::new_v4()? - } else { - TcpSocket::new_v6()? - }; - - socket.set_reuseaddr(true)?; - // #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))] - // socket.set_reuseport(true)?; - socket.bind(addr)?; + let socket2_socket = socket2::Socket::new( + socket2::Domain::for_address(addr), + socket2::Type::STREAM, + Some(socket2::Protocol::TCP), + )?; + setup_sokcet2(&socket2_socket, &addr)?; + let socket = TcpSocket::from_std_stream(socket2_socket.into()); self.addr .set_port(Some(socket.local_addr()?.port())) @@ -215,6 +212,14 @@ mod tests { _tunnel_pingpong(listener, connector).await } + #[tokio::test] + async fn bind_same_port() { + let mut listener = TcpTunnelListener::new("tcp://[::]:31014".parse().unwrap()); + let mut listener2 = TcpTunnelListener::new("tcp://0.0.0.0:31014".parse().unwrap()); + listener.listen().await.unwrap(); + listener2.listen().await.unwrap(); + } + #[tokio::test] async fn ipv6_pingpong() { let listener = TcpTunnelListener::new("tcp://[::1]:31015".parse().unwrap()); diff --git a/easytier/src/tunnel/udp.rs b/easytier/src/tunnel/udp.rs index d4d7c21..415385a 100644 --- a/easytier/src/tunnel/udp.rs +++ b/easytier/src/tunnel/udp.rs @@ -19,6 +19,7 @@ use crate::{ common::join_joinset_background, rpc::TunnelInfo, tunnel::{ + build_url_from_socket_addr, common::{reserve_buf, TunnelWrapper}, packet_def::{UdpPacketType, ZCPacket, ZCPacketType}, ring::RingTunnel, @@ -263,12 +264,12 @@ impl UdpTunnelListenerData { Some(TunnelInfo { tunnel_type: "udp".to_owned(), local_addr: self.local_url.clone().into(), - remote_addr: url::Url::parse(&format!("udp://{}", remote_addr)) - .unwrap() - .into(), + remote_addr: build_url_from_socket_addr(&remote_addr.to_string(), "udp").into(), }), )); + tracing::info!(info = ?conn.info().unwrap().remote_addr, "udp connection accept done"); + if let Err(e) = self.conn_send.send(conn).await { tracing::warn!(?e, "udp send conn to accept channel error"); } @@ -600,8 +601,7 @@ impl UdpTunnelConnector { Box::new(RingSink::new(ring_for_send_udp)), Some(TunnelInfo { tunnel_type: "udp".to_owned(), - local_addr: url::Url::parse(&format!("udp://{}", socket.local_addr()?)) - .unwrap() + local_addr: build_url_from_socket_addr(&socket.local_addr()?.to_string(), "udp") .into(), remote_addr: self.addr.clone().into(), }), @@ -867,6 +867,15 @@ mod tests { } } + #[tokio::test] + async fn bind_same_port() { + println!("{}", "[::]:8888".parse::().unwrap()); + let mut listener = UdpTunnelListener::new("udp://[::]:31014".parse().unwrap()); + let mut listener2 = UdpTunnelListener::new("udp://0.0.0.0:31014".parse().unwrap()); + listener.listen().await.unwrap(); + listener2.listen().await.unwrap(); + } + #[tokio::test] async fn ipv6_pingpong() { let listener = UdpTunnelListener::new("udp://[::1]:31015".parse().unwrap()); diff --git a/easytier/src/tunnel/wireguard.rs b/easytier/src/tunnel/wireguard.rs index b1cd804..5278d28 100644 --- a/easytier/src/tunnel/wireguard.rs +++ b/easytier/src/tunnel/wireguard.rs @@ -481,7 +481,6 @@ impl WgTunnelListener { let mut buf = vec![0u8; MAX_PACKET]; loop { - tracing::info!("Waiting for incoming UDP packet"); let Ok((n, addr)) = socket.recv_from(&mut buf).await else { tracing::error!("Failed to receive from UDP socket"); break; @@ -848,6 +847,16 @@ pub mod tests { assert_eq!(0, listener.wg_peer_map.len()); } + #[tokio::test] + async fn bind_same_port() { + let (server_cfg, _client_cfg) = create_wg_config(); + let mut listener = WgTunnelListener::new("wg://[::1]:31015".parse().unwrap(), server_cfg); + let (server_cfg, _client_cfg) = create_wg_config(); + let mut listener2 = WgTunnelListener::new("wg://[::1]:31015".parse().unwrap(), server_cfg); + listener.listen().await.unwrap(); + listener2.listen().await.unwrap(); + } + #[tokio::test] async fn ipv6_pingpong() { let (server_cfg, client_cfg) = create_wg_config();