allow use websocket (#11677)

1. Enable the RustDesk client to use WebSocket for either controlling or being controlled.
2. Fix TCP sending `register_pk` frequently

Note:
1. Because hbb_common directly uses `use_ws` to read config directly, rustdesk also directly reads config

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages
2025-05-09 12:18:49 +08:00
committed by GitHub
parent 86bbdf7a5d
commit 9475743b4e
61 changed files with 413 additions and 64 deletions

View File

@@ -12,7 +12,9 @@ use uuid::Uuid;
use hbb_common::{
allow_err,
anyhow::{self, bail},
config::{self, keys::*, option2bool, Config, CONNECT_TIMEOUT, REG_INTERVAL, RENDEZVOUS_PORT},
config::{
self, keys::*, option2bool, use_ws, Config, CONNECT_TIMEOUT, REG_INTERVAL, RENDEZVOUS_PORT,
},
futures::future::join_all,
log,
protobuf::Message as _,
@@ -139,6 +141,7 @@ impl RendezvousMediator {
pub async fn start_udp(server: ServerPtr, host: String) -> ResultType<()> {
let host = check_port(&host, RENDEZVOUS_PORT);
log::info!("start udp: {host}");
let (mut socket, mut addr) = socket_client::new_udp_for(&host, CONNECT_TIMEOUT).await?;
let mut rz = Self {
addr: addr.clone(),
@@ -323,6 +326,7 @@ impl RendezvousMediator {
pub async fn start_tcp(server: ServerPtr, host: String) -> ResultType<()> {
let host = check_port(&host, RENDEZVOUS_PORT);
log::info!("start tcp: {}", hbb_common::websocket::check_ws(&host));
let mut conn = connect_tcp(host.clone(), CONNECT_TIMEOUT).await?;
let key = crate::get_key(true).await;
crate::secure_tcp(&mut conn, &key).await?;
@@ -336,7 +340,7 @@ impl RendezvousMediator {
let mut last_register_sent: Option<Instant> = None;
let mut last_recv_msg = Instant::now();
// we won't support connecting to multiple rendzvous servers any more, so we can use a global variable here.
Config::set_host_key_confirmed(&host, false);
Config::set_host_key_confirmed(&rz.host_prefix, false);
loop {
let mut update_latency = || {
let latency = last_register_sent
@@ -350,6 +354,8 @@ impl RendezvousMediator {
last_recv_msg = Instant::now();
let bytes = res.ok_or_else(|| anyhow::anyhow!("Rendezvous connection is reset by the peer"))??;
if bytes.is_empty() {
// After fixing frequent register_pk, for websocket, nginx need to set proxy_read_timeout to more than 60 seconds, eg: 120s
// https://serverfault.com/questions/1060525/why-is-my-websocket-connection-gets-closed-in-60-seconds
conn.send_bytes(bytes::Bytes::new()).await?;
continue; // heartbeat
}
@@ -365,7 +371,7 @@ impl RendezvousMediator {
bail!("Rendezvous connection is timeout");
}
if (!Config::get_key_confirmed() ||
!Config::get_host_key_confirmed(&host)) &&
!Config::get_host_key_confirmed(&rz.host_prefix)) &&
last_register_sent.map(|x| x.elapsed().as_millis() as i64).unwrap_or(REG_INTERVAL) >= REG_INTERVAL {
rz.register_pk(Sink::Stream(&mut conn)).await?;
last_register_sent = Some(Instant::now());
@@ -380,7 +386,8 @@ impl RendezvousMediator {
log::info!("start rendezvous mediator of {}", host);
//If the investment agent type is http or https, then tcp forwarding is enabled.
if (cfg!(debug_assertions) && option_env!("TEST_TCP").is_some())
|| Config::is_proxy()
|| Config::is_proxy()
|| use_ws()
|| get_builtin_option(config::keys::OPTION_DISABLE_UDP) == "Y"
{
Self::start_tcp(server, host).await
@@ -449,7 +456,12 @@ impl RendezvousMediator {
async fn handle_intranet(&self, fla: FetchLocalAddr, server: ServerPtr) -> ResultType<()> {
let relay_server = self.get_relay_server(fla.relay_server.clone());
// nat64, go relay directly, because current hbbs will crash if demangle ipv6 address
if is_ipv4(&self.addr) && !config::is_disable_tcp_listen() && !Config::is_proxy() {
// websocket, go relay directly
if is_ipv4(&self.addr)
&& !config::is_disable_tcp_listen()
&& !Config::is_proxy()
&& !use_ws()
{
if let Err(err) = self
.handle_intranet_(fla.clone(), server.clone(), relay_server.clone())
.await
@@ -501,9 +513,12 @@ impl RendezvousMediator {
async fn handle_punch_hole(&self, ph: PunchHole, server: ServerPtr) -> ResultType<()> {
let relay_server = self.get_relay_server(ph.relay_server);
// for ensure, websocket go relay directly
if ph.nat_type.enum_value() == Ok(NatType::SYMMETRIC)
|| Config::get_nat_type() == NatType::SYMMETRIC as i32
|| config::is_disable_tcp_listen()
|| use_ws()
|| Config::is_proxy()
{
let uuid = Uuid::new_v4().to_string();
return self