try tcp and udp both

This commit is contained in:
RustDesk
2025-08-10 17:44:36 +08:00
committed by GitHub
parent 4263643200
commit 1954790808

View File

@@ -279,10 +279,10 @@ impl Client {
} }
let (stop_udp_tx, stop_udp_rx) = oneshot::channel::<()>(); let (stop_udp_tx, stop_udp_rx) = oneshot::channel::<()>();
let mut udp = let udp =
// no need to care about multiple rendezvous servers case, since it is acutally not used any more. // no need to care about multiple rendezvous servers case, since it is acutally not used any more.
// Shared state for UDP NAT test result // Shared state for UDP NAT test result
if crate::get_udp_punch_enabled() { if crate::get_udp_punch_enabled() && !interface.is_force_relay() {
if let Ok((socket, addr)) = new_direct_udp_for(&rendezvous_server).await { if let Ok((socket, addr)) = new_direct_udp_for(&rendezvous_server).await {
let udp_port = Arc::new(Mutex::new(0)); let udp_port = Arc::new(Mutex::new(0));
let up_cloned = udp_port.clone(); let up_cloned = udp_port.clone();
@@ -298,6 +298,57 @@ impl Client {
} else { } else {
(None, None) (None, None)
}; };
let fut = Self::_start_inner(
peer.to_owned(),
key.to_owned(),
token.to_owned(),
conn_type,
interface.clone(),
udp.clone(),
Some(stop_udp_tx),
rendezvous_server.clone(),
servers.clone(),
contained,
);
if udp.0.is_none() {
return fut.await;
}
let mut connect_futures = Vec::new();
connect_futures.push(fut.boxed());
let fut = Self::_start_inner(
peer.to_owned(),
key.to_owned(),
token.to_owned(),
conn_type,
interface,
(None, None),
None,
rendezvous_server,
servers,
contained,
);
connect_futures.push(fut.boxed());
match select_ok(connect_futures).await {
Ok(conn) => Ok((conn.0 .0, conn.0 .1)),
Err(e) => Err(e),
}
}
async fn _start_inner(
peer: String,
key: String,
token: String,
conn_type: ConnType,
interface: impl Interface,
mut udp: (Option<Arc<UdpSocket>>, Option<Arc<Mutex<u16>>>),
stop_udp_tx: Option<oneshot::Sender<()>>,
mut rendezvous_server: String,
servers: Vec<String>,
contained: bool,
) -> ResultType<(
(Stream, bool, Option<Vec<u8>>, Option<KcpStream>),
(i32, String),
)> {
let mut start = Instant::now(); let mut start = Instant::now();
let mut socket = connect_tcp(&*rendezvous_server, CONNECT_TIMEOUT).await; let mut socket = connect_tcp(&*rendezvous_server, CONNECT_TIMEOUT).await;
debug_assert!(!servers.contains(&rendezvous_server)); debug_assert!(!servers.contains(&rendezvous_server));
@@ -327,9 +378,8 @@ impl Client {
let my_nat_type = crate::get_nat_type(100).await; let my_nat_type = crate::get_nat_type(100).await;
let mut is_local = false; let mut is_local = false;
let mut feedback = 0; let mut feedback = 0;
let force_relay = interface.is_force_relay() || use_ws() || Config::is_proxy();
use hbb_common::protobuf::Enum; use hbb_common::protobuf::Enum;
let nat_type = if force_relay { let nat_type = if interface.is_force_relay() {
NatType::SYMMETRIC NatType::SYMMETRIC
} else { } else {
NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT) NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT)
@@ -337,7 +387,7 @@ impl Client {
if !key.is_empty() && !token.is_empty() { if !key.is_empty() && !token.is_empty() {
// mainly for the security of token // mainly for the security of token
secure_tcp(&mut socket, key) secure_tcp(&mut socket, &key)
.await .await
.map_err(|e| anyhow!("Failed to secure tcp: {}", e))?; .map_err(|e| anyhow!("Failed to secure tcp: {}", e))?;
} else if let Some(udp) = udp.1.as_ref() { } else if let Some(udp) = udp.1.as_ref() {
@@ -355,7 +405,7 @@ impl Client {
} }
} }
// Stop UDP NAT test task if still running // Stop UDP NAT test task if still running
let _ = stop_udp_tx.send(()); stop_udp_tx.map(|tx| tx.send(()));
let mut msg_out = RendezvousMessage::new(); let mut msg_out = RendezvousMessage::new();
let mut ipv6 = if crate::get_ipv6_punch_enabled() { let mut ipv6 = if crate::get_ipv6_punch_enabled() {
if let Some((socket, addr)) = crate::get_ipv6_socket().await { if let Some((socket, addr)) = crate::get_ipv6_socket().await {
@@ -375,7 +425,7 @@ impl Client {
conn_type: conn_type.into(), conn_type: conn_type.into(),
version: crate::VERSION.to_owned(), version: crate::VERSION.to_owned(),
udp_port: udp_nat_port as _, udp_port: udp_nat_port as _,
force_relay, force_relay: interface.is_force_relay(),
socket_addr_v6: ipv6.1.unwrap_or_default(), socket_addr_v6: ipv6.1.unwrap_or_default(),
..Default::default() ..Default::default()
}); });
@@ -454,10 +504,10 @@ impl Client {
} }
signed_id_pk = rr.pk().into(); signed_id_pk = rr.pk().into();
let fut = Self::create_relay( let fut = Self::create_relay(
peer, &peer,
rr.uuid, rr.uuid,
rr.relay_server, rr.relay_server,
key, &key,
conn_type, conn_type,
my_addr.is_ipv4(), my_addr.is_ipv4(),
); );
@@ -478,7 +528,7 @@ impl Client {
feedback = rr.feedback; feedback = rr.feedback;
log::info!("{:?} used to establish {typ} connection", start.elapsed()); log::info!("{:?} used to establish {typ} connection", start.elapsed());
let pk = let pk =
Self::secure_connection(peer, signed_id_pk, key, &mut conn).await?; Self::secure_connection(&peer, signed_id_pk, &key, &mut conn).await?;
return Ok(((conn, false, pk, kcp), (feedback, rendezvous_server))); return Ok(((conn, false, pk, kcp), (feedback, rendezvous_server)));
} }
_ => { _ => {
@@ -506,7 +556,7 @@ impl Client {
Self::connect( Self::connect(
my_addr, my_addr,
peer_addr, peer_addr,
peer, &peer,
signed_id_pk, signed_id_pk,
&relay_server, &relay_server,
&rendezvous_server, &rendezvous_server,
@@ -514,8 +564,8 @@ impl Client {
peer_nat_type, peer_nat_type,
my_nat_type, my_nat_type,
is_local, is_local,
key, &key,
token, &token,
conn_type, conn_type,
interface, interface,
udp.0, udp.0,
@@ -1731,7 +1781,9 @@ impl LoginConfigHandler {
self.restarting_remote_device = false; self.restarting_remote_device = false;
self.force_relay = self.force_relay =
config::option2bool("force-always-relay", &self.get_option("force-always-relay")) config::option2bool("force-always-relay", &self.get_option("force-always-relay"))
|| force_relay; || force_relay
|| use_ws()
|| Config::is_proxy();
if let Some((real_id, server, key)) = &self.other_server { if let Some((real_id, server, key)) = &self.other_server {
let other_server_key = self.get_option("other-server-key"); let other_server_key = self.get_option("other-server-key");
if !other_server_key.is_empty() && key.is_empty() { if !other_server_key.is_empty() && key.is_empty() {