connection type

This commit is contained in:
rustdesk 2021-07-27 23:53:12 +08:00
parent a3f5ffc15a
commit e6744d031d
7 changed files with 76 additions and 17 deletions

View File

@ -6,11 +6,19 @@ message RegisterPeer {
int32 serial = 2; int32 serial = 2;
} }
enum ConnType {
DEFAULT_CONN = 0;
FILE_TRANSFER = 1;
PORT_FORWARD = 2;
RDP = 3;
}
message RegisterPeerResponse { bool request_pk = 2; } message RegisterPeerResponse { bool request_pk = 2; }
message PunchHoleRequest { message PunchHoleRequest {
string id = 1; string id = 1;
NatType nat_type = 2; NatType nat_type = 2;
ConnType conn_type = 4;
} }
message PunchHole { message PunchHole {
@ -52,6 +60,11 @@ message RegisterPkResponse {
enum Result { enum Result {
OK = 1; OK = 1;
UUID_MISMATCH = 2; UUID_MISMATCH = 2;
ID_EXISTS = 3;
TOO_FREQUENT = 4;
INVALID_ID_FORMAT = 5;
NOT_SUPPORT = 6;
SERVER_ERROR = 7;
} }
Result result = 1; Result result = 1;
} }
@ -62,6 +75,8 @@ message PunchHoleResponse {
enum Failure { enum Failure {
ID_NOT_EXIST = 1; ID_NOT_EXIST = 1;
OFFLINE = 2; OFFLINE = 2;
LICENCE_MISMATCH = 3;
LICENCE_OVERUSE = 4;
} }
Failure failure = 3; Failure failure = 3;
string relay_server = 4; string relay_server = 4;
@ -69,6 +84,7 @@ message PunchHoleResponse {
NatType nat_type = 5; NatType nat_type = 5;
bool is_local = 6; bool is_local = 6;
} }
string other_failure = 7;
} }
message ConfigUpdate { message ConfigUpdate {
@ -82,6 +98,7 @@ message RequestRelay {
bytes socket_addr = 3; bytes socket_addr = 3;
string relay_server = 4; string relay_server = 4;
bool secure = 5; bool secure = 5;
ConnType conn_type = 7;
} }
message RelayResponse { message RelayResponse {
@ -92,6 +109,7 @@ message RelayResponse {
string id = 4; string id = 4;
bytes pk = 5; bytes pk = 5;
} }
string refuse_reason = 6;
} }
message SoftwareUpdate { string url = 1; } message SoftwareUpdate { string url = 1; }

View File

@ -27,7 +27,7 @@ fn find_package(name: &str) -> Vec<PathBuf> {
println!("cargo:info={}", target); println!("cargo:info={}", target);
path.push("installed"); path.push("installed");
path.push(target); path.push(target);
let mut lib = name.trim_start_matches("lib").to_string(); let lib = name.trim_start_matches("lib").to_string();
println!("{}", format!("cargo:rustc-link-lib=static={}", lib)); println!("{}", format!("cargo:rustc-link-lib=static={}", lib));
println!( println!(
"{}", "{}",

View File

@ -100,7 +100,7 @@ impl Drop for OboePlayer {
} }
impl Client { impl Client {
pub async fn start(peer: &str) -> ResultType<(Stream, bool)> { pub async fn start(peer: &str, conn_type: ConnType) -> ResultType<(Stream, bool)> {
// to-do: remember the port for each peer, so that we can retry easier // to-do: remember the port for each peer, so that we can retry easier
let any_addr = Config::get_any_listen_addr(); let any_addr = Config::get_any_listen_addr();
let rendezvous_server = crate::get_rendezvous_server(1_000).await; let rendezvous_server = crate::get_rendezvous_server(1_000).await;
@ -125,6 +125,7 @@ impl Client {
msg_out.set_punch_hole_request(PunchHoleRequest { msg_out.set_punch_hole_request(PunchHoleRequest {
id: peer.to_owned(), id: peer.to_owned(),
nat_type: nat_type.into(), nat_type: nat_type.into(),
conn_type: conn_type.into(),
..Default::default() ..Default::default()
}); });
socket.send(&msg_out).await?; socket.send(&msg_out).await?;
@ -140,7 +141,14 @@ impl Client {
punch_hole_response::Failure::OFFLINE => { punch_hole_response::Failure::OFFLINE => {
bail!("Remote desktop is offline"); bail!("Remote desktop is offline");
} }
_ => {} punch_hole_response::Failure::LICENCE_MISMATCH => {
bail!("Key mismatch");
}
_ => {
if !ph.other_failure.is_empty() {
bail!(ph.other_failure);
}
}
} }
} else { } else {
peer_nat_type = ph.get_nat_type(); peer_nat_type = ph.get_nat_type();
@ -160,7 +168,8 @@ impl Client {
); );
pk = rr.get_pk().into(); pk = rr.get_pk().into();
let mut conn = let mut conn =
Self::create_relay(peer, rr.uuid, rr.relay_server).await?; Self::create_relay(peer, rr.uuid, rr.relay_server, conn_type)
.await?;
Self::secure_connection(peer, pk, &mut conn).await?; Self::secure_connection(peer, pk, &mut conn).await?;
return Ok((conn, false)); return Ok((conn, false));
} }
@ -199,6 +208,7 @@ impl Client {
peer_nat_type, peer_nat_type,
my_nat_type, my_nat_type,
is_local, is_local,
conn_type,
) )
.await .await
} }
@ -214,8 +224,9 @@ impl Client {
peer_nat_type: NatType, peer_nat_type: NatType,
my_nat_type: i32, my_nat_type: i32,
is_local: bool, is_local: bool,
conn_type: ConnType,
) -> ResultType<(Stream, bool)> { ) -> ResultType<(Stream, bool)> {
let mut direct_failures = 0; let direct_failures = PeerConfig::load(peer_id).direct_failures;
let mut connect_timeout = 0; let mut connect_timeout = 0;
const MIN: u64 = 1000; const MIN: u64 = 1000;
if is_local || peer_nat_type == NatType::SYMMETRIC { if is_local || peer_nat_type == NatType::SYMMETRIC {
@ -231,13 +242,14 @@ impl Client {
} }
if my_nat_type == NatType::ASYMMETRIC as i32 { if my_nat_type == NatType::ASYMMETRIC as i32 {
connect_timeout = CONNECT_TIMEOUT; connect_timeout = CONNECT_TIMEOUT;
if direct_failures > 0 {
connect_timeout = punch_time_used * 6;
}
} else if my_nat_type == NatType::SYMMETRIC as i32 { } else if my_nat_type == NatType::SYMMETRIC as i32 {
connect_timeout = MIN; connect_timeout = MIN;
} }
} }
if connect_timeout == 0 { if connect_timeout == 0 {
let config = PeerConfig::load(peer_id);
direct_failures = config.direct_failures;
let n = if direct_failures > 0 { 3 } else { 6 }; let n = if direct_failures > 0 { 3 } else { 6 };
connect_timeout = punch_time_used * (n as u64); connect_timeout = punch_time_used * (n as u64);
} }
@ -257,10 +269,14 @@ impl Client {
relay_server.to_owned(), relay_server.to_owned(),
rendezvous_server, rendezvous_server,
pk.len() == sign::PUBLICKEYBYTES, pk.len() == sign::PUBLICKEYBYTES,
conn_type,
) )
.await; .await;
if conn.is_err() { if conn.is_err() {
bail!("Failed to connect via relay server"); bail!(
"Failed to connect via relay server: {}",
conn.err().unwrap()
);
} }
} else { } else {
bail!("Failed to make direct connection to remote desktop"); bail!("Failed to make direct connection to remote desktop");
@ -318,7 +334,7 @@ impl Client {
} }
} else { } else {
// fall back to non-secure connection in case pk mismatch // fall back to non-secure connection in case pk mismatch
// to-do: pop up a warning dialog to let user choose if continue log::info!("pk mismatch, fall back to non-secure");
let mut msg_out = Message::new(); let mut msg_out = Message::new();
msg_out.set_public_key(PublicKey::new()); msg_out.set_public_key(PublicKey::new());
timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??; timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??;
@ -342,6 +358,7 @@ impl Client {
relay_server: String, relay_server: String,
rendezvous_server: SocketAddr, rendezvous_server: SocketAddr,
secure: bool, secure: bool,
conn_type: ConnType,
) -> ResultType<Stream> { ) -> ResultType<Stream> {
let any_addr = Config::get_any_listen_addr(); let any_addr = Config::get_any_listen_addr();
let mut succeed = false; let mut succeed = false;
@ -371,7 +388,10 @@ impl Client {
socket.send(&msg_out).await?; socket.send(&msg_out).await?;
if let Some(Ok(bytes)) = socket.next_timeout(i * 3000).await { if let Some(Ok(bytes)) = socket.next_timeout(i * 3000).await {
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) { if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
if let Some(rendezvous_message::Union::relay_response(_)) = msg_in.union { if let Some(rendezvous_message::Union::relay_response(rs)) = msg_in.union {
if !rs.refuse_reason.is_empty() {
bail!(rs.refuse_reason);
}
succeed = true; succeed = true;
break; break;
} }
@ -381,10 +401,15 @@ impl Client {
if !succeed { if !succeed {
bail!(""); bail!("");
} }
Self::create_relay(peer, uuid, relay_server).await Self::create_relay(peer, uuid, relay_server, conn_type).await
} }
async fn create_relay(peer: &str, uuid: String, relay_server: String) -> ResultType<Stream> { async fn create_relay(
peer: &str,
uuid: String,
relay_server: String,
conn_type: ConnType,
) -> ResultType<Stream> {
let mut conn = FramedStream::new( let mut conn = FramedStream::new(
crate::check_port(relay_server, RELAY_PORT), crate::check_port(relay_server, RELAY_PORT),
Config::get_any_listen_addr(), Config::get_any_listen_addr(),
@ -396,6 +421,7 @@ impl Client {
msg_out.set_request_relay(RequestRelay { msg_out.set_request_relay(RequestRelay {
id: peer.to_owned(), id: peer.to_owned(),
uuid, uuid,
conn_type: conn_type.into(),
..Default::default() ..Default::default()
}); });
conn.send(&msg_out).await?; conn.send(&msg_out).await?;

View File

@ -6,6 +6,7 @@ use hbb_common::{
log, log,
message_proto::*, message_proto::*,
protobuf::Message as _, protobuf::Message as _,
rendezvous_proto::ConnType,
tcp, timeout, tcp, timeout,
tokio::{self, net::TcpStream, sync::mpsc}, tokio::{self, net::TcpStream, sync::mpsc},
tokio_util::codec::{BytesCodec, Framed}, tokio_util::codec::{BytesCodec, Framed},
@ -39,7 +40,7 @@ pub async fn listen(
log::info!("new connection from {:?}", addr); log::info!("new connection from {:?}", addr);
let id = id.clone(); let id = id.clone();
let mut forward = Framed::new(forward, BytesCodec::new()); let mut forward = Framed::new(forward, BytesCodec::new());
match connect_and_login(&id, &mut ui_receiver, interface.clone(), &mut forward).await { match connect_and_login(&id, &mut ui_receiver, interface.clone(), &mut forward, is_rdp).await {
Ok(Some(stream)) => { Ok(Some(stream)) => {
let interface = interface.clone(); let interface = interface.clone();
tokio::spawn(async move { tokio::spawn(async move {
@ -76,8 +77,14 @@ async fn connect_and_login(
ui_receiver: &mut mpsc::UnboundedReceiver<Data>, ui_receiver: &mut mpsc::UnboundedReceiver<Data>,
interface: impl Interface, interface: impl Interface,
forward: &mut Framed<TcpStream, BytesCodec>, forward: &mut Framed<TcpStream, BytesCodec>,
is_rdp: bool,
) -> ResultType<Option<Stream>> { ) -> ResultType<Option<Stream>> {
let (mut stream, _) = Client::start(&id).await?; let conn_type = if is_rdp {
ConnType::RDP
} else {
ConnType::PORT_FORWARD
};
let (mut stream, _) = Client::start(id, conn_type).await?;
let mut interface = interface; let mut interface = interface;
let mut buffer = Vec::new(); let mut buffer = Vec::new();
loop { loop {

View File

@ -155,6 +155,7 @@ impl RendezvousMediator {
register_pk_response::Result::UUID_MISMATCH => { register_pk_response::Result::UUID_MISMATCH => {
allow_err!(rz.handle_uuid_mismatch(&mut socket).await); allow_err!(rz.handle_uuid_mismatch(&mut socket).await);
} }
_ => {}
} }
} }
Some(rendezvous_message::Union::punch_hole(ph)) => { Some(rendezvous_message::Union::punch_hole(ph)) => {

View File

@ -511,9 +511,9 @@ impl UI {
format!("{}.{}", p.to_string_lossy(), self.get_software_ext()) format!("{}.{}", p.to_string_lossy(), self.get_software_ext())
} }
fn create_shortcut(&self, id: String) { fn create_shortcut(&self, _id: String) {
#[cfg(windows)] #[cfg(windows)]
crate::platform::windows::create_shortcut(&id).ok(); crate::platform::windows::create_shortcut(&_id).ok();
} }
fn open_url(&self, url: String) { fn open_url(&self, url: String) {

View File

@ -9,6 +9,7 @@ use hbb_common::{
fs, log, fs, log,
message_proto::*, message_proto::*,
protobuf::Message as _, protobuf::Message as _,
rendezvous_proto::ConnType,
sleep, sleep,
tokio::{ tokio::{
self, self,
@ -494,6 +495,7 @@ impl Handler {
fn set_no_confirm(&mut self, id: i32) { fn set_no_confirm(&mut self, id: i32) {
self.send(Data::SetNoConfirm(id)); self.send(Data::SetNoConfirm(id));
} }
fn remove_dir(&mut self, id: i32, path: String, is_remote: bool) { fn remove_dir(&mut self, id: i32, path: String, is_remote: bool) {
if is_remote { if is_remote {
self.send(Data::RemoveDir((id, path))); self.send(Data::RemoveDir((id, path)));
@ -1144,7 +1146,12 @@ impl Remote {
async fn io_loop(&mut self) { async fn io_loop(&mut self) {
let stop_clipboard = self.start_clipboard(); let stop_clipboard = self.start_clipboard();
let mut last_recv_time = Instant::now(); let mut last_recv_time = Instant::now();
match Client::start(&self.handler.id).await { let conn_type = if self.handler.is_file_transfer() {
ConnType::FILE_TRANSFER
} else {
ConnType::default()
};
match Client::start(&self.handler.id, conn_type).await {
Ok((mut peer, direct)) => { Ok((mut peer, direct)) => {
self.handler self.handler
.call("setConnectionType", &make_args!(peer.is_secured(), direct)); .call("setConnectionType", &make_args!(peer.is_secured(), direct));