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

View File

@ -27,7 +27,7 @@ fn find_package(name: &str) -> Vec<PathBuf> {
println!("cargo:info={}", target);
path.push("installed");
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!(
"{}",

View File

@ -100,7 +100,7 @@ impl Drop for OboePlayer {
}
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
let any_addr = Config::get_any_listen_addr();
let rendezvous_server = crate::get_rendezvous_server(1_000).await;
@ -125,6 +125,7 @@ impl Client {
msg_out.set_punch_hole_request(PunchHoleRequest {
id: peer.to_owned(),
nat_type: nat_type.into(),
conn_type: conn_type.into(),
..Default::default()
});
socket.send(&msg_out).await?;
@ -140,7 +141,14 @@ impl Client {
punch_hole_response::Failure::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 {
peer_nat_type = ph.get_nat_type();
@ -160,7 +168,8 @@ impl Client {
);
pk = rr.get_pk().into();
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?;
return Ok((conn, false));
}
@ -199,6 +208,7 @@ impl Client {
peer_nat_type,
my_nat_type,
is_local,
conn_type,
)
.await
}
@ -214,8 +224,9 @@ impl Client {
peer_nat_type: NatType,
my_nat_type: i32,
is_local: bool,
conn_type: ConnType,
) -> ResultType<(Stream, bool)> {
let mut direct_failures = 0;
let direct_failures = PeerConfig::load(peer_id).direct_failures;
let mut connect_timeout = 0;
const MIN: u64 = 1000;
if is_local || peer_nat_type == NatType::SYMMETRIC {
@ -231,13 +242,14 @@ impl Client {
}
if my_nat_type == NatType::ASYMMETRIC as i32 {
connect_timeout = CONNECT_TIMEOUT;
if direct_failures > 0 {
connect_timeout = punch_time_used * 6;
}
} else if my_nat_type == NatType::SYMMETRIC as i32 {
connect_timeout = MIN;
}
}
if connect_timeout == 0 {
let config = PeerConfig::load(peer_id);
direct_failures = config.direct_failures;
let n = if direct_failures > 0 { 3 } else { 6 };
connect_timeout = punch_time_used * (n as u64);
}
@ -257,10 +269,14 @@ impl Client {
relay_server.to_owned(),
rendezvous_server,
pk.len() == sign::PUBLICKEYBYTES,
conn_type,
)
.await;
if conn.is_err() {
bail!("Failed to connect via relay server");
bail!(
"Failed to connect via relay server: {}",
conn.err().unwrap()
);
}
} else {
bail!("Failed to make direct connection to remote desktop");
@ -318,7 +334,7 @@ impl Client {
}
} else {
// 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();
msg_out.set_public_key(PublicKey::new());
timeout(CONNECT_TIMEOUT, conn.send(&msg_out)).await??;
@ -342,6 +358,7 @@ impl Client {
relay_server: String,
rendezvous_server: SocketAddr,
secure: bool,
conn_type: ConnType,
) -> ResultType<Stream> {
let any_addr = Config::get_any_listen_addr();
let mut succeed = false;
@ -371,7 +388,10 @@ impl Client {
socket.send(&msg_out).await?;
if let Some(Ok(bytes)) = socket.next_timeout(i * 3000).await {
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;
break;
}
@ -381,10 +401,15 @@ impl Client {
if !succeed {
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(
crate::check_port(relay_server, RELAY_PORT),
Config::get_any_listen_addr(),
@ -396,6 +421,7 @@ impl Client {
msg_out.set_request_relay(RequestRelay {
id: peer.to_owned(),
uuid,
conn_type: conn_type.into(),
..Default::default()
});
conn.send(&msg_out).await?;

View File

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

View File

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

View File

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

View File

@ -9,6 +9,7 @@ use hbb_common::{
fs, log,
message_proto::*,
protobuf::Message as _,
rendezvous_proto::ConnType,
sleep,
tokio::{
self,
@ -494,6 +495,7 @@ impl Handler {
fn set_no_confirm(&mut self, id: i32) {
self.send(Data::SetNoConfirm(id));
}
fn remove_dir(&mut self, id: i32, path: String, is_remote: bool) {
if is_remote {
self.send(Data::RemoveDir((id, path)));
@ -1144,7 +1146,12 @@ impl Remote {
async fn io_loop(&mut self) {
let stop_clipboard = self.start_clipboard();
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)) => {
self.handler
.call("setConnectionType", &make_args!(peer.is_secured(), direct));