Merge branch 'master' into flutter_desktop

This commit is contained in:
21pages
2022-08-25 11:50:30 +08:00
43 changed files with 1282 additions and 85 deletions

View File

@@ -20,7 +20,10 @@ use hbb_common::{
allow_err,
anyhow::{anyhow, Context},
bail,
config::{Config, PeerConfig, PeerInfoSerde, CONNECT_TIMEOUT, RELAY_PORT, RENDEZVOUS_TIMEOUT},
config::{
Config, PeerConfig, PeerInfoSerde, CONNECT_TIMEOUT, READ_TIMEOUT, RELAY_PORT,
RENDEZVOUS_TIMEOUT,
},
log,
message_proto::{option_message::BoolOption, *},
protobuf::Message as _,
@@ -121,8 +124,9 @@ impl Client {
key: &str,
token: &str,
conn_type: ConnType,
interface: impl Interface,
) -> ResultType<(Stream, bool)> {
match Self::_start(peer, key, token, conn_type).await {
match Self::_start(peer, key, token, conn_type, interface).await {
Err(err) => {
let err_str = err.to_string();
if err_str.starts_with("Failed") {
@@ -141,6 +145,7 @@ impl Client {
key: &str,
token: &str,
conn_type: ConnType,
interface: impl Interface,
) -> ResultType<(Stream, bool)> {
// to-do: remember the port for each peer, so that we can retry easier
let any_addr = Config::get_any_listen_addr();
@@ -187,7 +192,11 @@ impl Client {
log::info!("#{} punch attempt with {}, id: {}", i, my_addr, peer);
let mut msg_out = RendezvousMessage::new();
use hbb_common::protobuf::Enum;
let nat_type = NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT);
let nat_type = if interface.is_force_relay() {
NatType::SYMMETRIC
} else {
NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT)
};
msg_out.set_punch_hole_request(PunchHoleRequest {
id: peer.to_owned(),
token: token.to_owned(),
@@ -239,7 +248,15 @@ impl Client {
let mut conn =
Self::create_relay(peer, rr.uuid, rr.relay_server, key, conn_type)
.await?;
Self::secure_connection(peer, signed_id_pk, key, &mut conn).await?;
Self::secure_connection(
peer,
signed_id_pk,
key,
&mut conn,
false,
interface,
)
.await?;
return Ok((conn, false));
}
_ => {
@@ -280,6 +297,7 @@ impl Client {
key,
token,
conn_type,
interface,
)
.await
}
@@ -299,6 +317,7 @@ impl Client {
key: &str,
token: &str,
conn_type: ConnType,
interface: impl Interface,
) -> ResultType<(Stream, bool)> {
let direct_failures = PeerConfig::load(peer_id).direct_failures;
let mut connect_timeout = 0;
@@ -336,8 +355,8 @@ impl Client {
let start = std::time::Instant::now();
// NOTICE: Socks5 is be used event in intranet. Which may be not a good way.
let mut conn = socket_client::connect_tcp(peer, local_addr, connect_timeout).await;
let direct = !conn.is_err();
if conn.is_err() {
let mut direct = !conn.is_err();
if interface.is_force_relay() || conn.is_err() {
if !relay_server.is_empty() {
conn = Self::request_relay(
peer_id,
@@ -355,6 +374,7 @@ impl Client {
conn.err().unwrap()
);
}
direct = false;
} else {
bail!("Failed to make direct connection to remote desktop");
}
@@ -367,7 +387,7 @@ impl Client {
}
let mut conn = conn?;
log::info!("{:?} used to establish connection", start.elapsed());
Self::secure_connection(peer_id, signed_id_pk, key, &mut conn).await?;
Self::secure_connection(peer_id, signed_id_pk, key, &mut conn, direct, interface).await?;
Ok((conn, direct))
}
@@ -377,6 +397,8 @@ impl Client {
signed_id_pk: Vec<u8>,
key: &str,
conn: &mut Stream,
direct: bool,
mut interface: impl Interface,
) -> ResultType<()> {
let rs_pk = get_rs_pk(if key.is_empty() {
hbb_common::config::RS_PUB_KEY
@@ -402,9 +424,15 @@ impl Client {
return Ok(());
}
};
match timeout(CONNECT_TIMEOUT, conn.next()).await? {
match timeout(READ_TIMEOUT, conn.next()).await? {
Some(res) => {
let bytes = res?;
let bytes = match res {
Ok(bytes) => bytes,
Err(err) => {
interface.set_force_relay(direct, false);
bail!("{}", err);
}
};
if let Ok(msg_in) = Message::parse_from_bytes(&bytes) {
if let Some(message::Union::SignedId(si)) = msg_in.union {
if let Ok((id, their_pk_b)) = decode_id_pk(&si.id, &sign_pk) {
@@ -831,6 +859,7 @@ pub struct LoginConfigHandler {
session_id: u64,
pub supported_encoding: Option<(bool, bool)>,
pub restarting_remote_device: bool,
pub force_relay: bool,
}
impl Deref for LoginConfigHandler {
@@ -869,6 +898,7 @@ impl LoginConfigHandler {
self.session_id = rand::random();
self.supported_encoding = None;
self.restarting_remote_device = false;
self.force_relay = !self.get_option("force-always-relay").is_empty();
}
/// Check if the client should auto login.
@@ -1620,6 +1650,8 @@ pub trait Interface: Send + Clone + 'static + Sized {
fn msgbox(&self, msgtype: &str, title: &str, text: &str);
fn handle_login_error(&mut self, err: &str) -> bool;
fn handle_peer_info(&mut self, pi: PeerInfo);
fn set_force_relay(&mut self, direct: bool, received: bool);
fn is_force_relay(&self) -> bool;
async fn handle_hash(&mut self, pass: &str, hash: Hash, peer: &mut Stream);
async fn handle_login_from_ui(&mut self, password: String, remember: bool, peer: &mut Stream);
async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream);
@@ -1790,14 +1822,16 @@ lazy_static::lazy_static! {
pub fn check_if_retry(msgtype: &str, title: &str, text: &str) -> bool {
msgtype == "error"
&& title == "Connection Error"
&& !text.to_lowercase().contains("offline")
&& !text.to_lowercase().contains("exist")
&& !text.to_lowercase().contains("handshake")
&& !text.to_lowercase().contains("failed")
&& !text.to_lowercase().contains("resolve")
&& !text.to_lowercase().contains("mismatch")
&& !text.to_lowercase().contains("manually")
&& !text.to_lowercase().contains("not allowed")
&& (text.contains("10054")
|| text.contains("104")
|| (!text.to_lowercase().contains("offline")
&& !text.to_lowercase().contains("exist")
&& !text.to_lowercase().contains("handshake")
&& !text.to_lowercase().contains("failed")
&& !text.to_lowercase().contains("resolve")
&& !text.to_lowercase().contains("mismatch")
&& !text.to_lowercase().contains("manually")
&& !text.to_lowercase().contains("not allowed")))
}
#[inline]