rustdesk-server/src/rendezvous_server.rs

523 lines
19 KiB
Rust
Raw Normal View History

2020-03-07 23:24:58 +08:00
use hbb_common::{
2020-05-11 12:57:55 +08:00
allow_err,
2020-05-15 03:16:46 +08:00
bytes::{Bytes, BytesMut},
2020-05-11 12:57:55 +08:00
bytes_codec::BytesCodec,
futures_util::{
sink::SinkExt,
stream::{SplitSink, StreamExt},
},
log,
2020-09-04 11:32:42 +08:00
protobuf::Message as _,
2020-05-11 12:57:55 +08:00
rendezvous_proto::*,
tcp::new_listener,
2020-09-18 00:47:15 +08:00
timeout,
2020-05-11 12:57:55 +08:00
tokio::{self, net::TcpStream, sync::mpsc},
tokio_util::codec::Framed,
udp::FramedSocket,
AddrMangle, ResultType,
};
2020-05-15 03:16:46 +08:00
use serde_derive::{Deserialize, Serialize};
2020-05-11 12:57:55 +08:00
use std::{
collections::HashMap,
net::SocketAddr,
2020-05-14 19:47:28 +08:00
sync::{Arc, Mutex, RwLock},
2020-05-11 12:57:55 +08:00
time::Instant,
2020-03-07 02:06:17 +08:00
};
2020-03-06 17:18:22 +08:00
2020-09-08 17:16:11 +08:00
#[derive(Clone, Debug)]
2020-05-14 17:18:07 +08:00
struct Peer {
2020-03-09 16:16:21 +08:00
socket_addr: SocketAddr,
2020-04-30 10:57:54 +08:00
last_reg_time: Instant,
2020-09-08 16:18:33 +08:00
uuid: Vec<u8>,
2020-07-09 00:56:30 +08:00
pk: Vec<u8>,
2020-03-06 17:18:22 +08:00
}
impl Default for Peer {
fn default() -> Self {
Self {
socket_addr: "0.0.0.0:0".parse().unwrap(),
last_reg_time: Instant::now()
.checked_sub(std::time::Duration::from_secs(3600))
.unwrap(),
2020-09-08 16:18:33 +08:00
uuid: Vec::new(),
2020-07-09 00:56:30 +08:00
pk: Vec::new(),
}
}
}
2020-05-15 03:16:46 +08:00
#[derive(Debug, Serialize, Deserialize, Default)]
struct PeerSerde {
#[serde(default)]
ip: String,
2020-07-09 00:56:30 +08:00
#[serde(default)]
2020-09-08 16:18:33 +08:00
uuid: Vec<u8>,
#[serde(default)]
2020-07-09 00:56:30 +08:00
pk: Vec<u8>,
2020-05-15 03:16:46 +08:00
}
2020-05-14 19:47:28 +08:00
#[derive(Clone)]
2020-05-14 17:18:07 +08:00
struct PeerMap {
2020-05-14 19:47:28 +08:00
map: Arc<RwLock<HashMap<String, Peer>>>,
2020-05-15 03:16:46 +08:00
db: super::SledAsync,
2020-05-14 17:18:07 +08:00
}
impl PeerMap {
fn new() -> ResultType<Self> {
Ok(Self {
2020-05-14 19:47:28 +08:00
map: Default::default(),
db: super::SledAsync::new("./sled.db", true)?,
2020-05-14 17:18:07 +08:00
})
}
2020-05-14 19:47:28 +08:00
#[inline]
2020-09-08 16:18:33 +08:00
fn update_pk(&mut self, id: String, socket_addr: SocketAddr, uuid: Vec<u8>, pk: Vec<u8>) {
2020-09-11 00:34:02 +08:00
log::info!("update_pk {} {:?} {:?} {:?}", id, socket_addr, uuid, pk);
2020-07-09 00:56:30 +08:00
let mut lock = self.map.write().unwrap();
lock.insert(
2020-07-09 02:16:59 +08:00
id.clone(),
2020-07-09 00:56:30 +08:00
Peer {
socket_addr,
last_reg_time: Instant::now(),
2020-09-08 16:18:33 +08:00
uuid: uuid.clone(),
2020-07-09 00:56:30 +08:00
pk: pk.clone(),
},
);
2020-09-08 17:16:11 +08:00
drop(lock);
2020-07-09 00:56:30 +08:00
let ip = socket_addr.ip().to_string();
2020-09-08 16:18:33 +08:00
self.db.insert(id, PeerSerde { ip, uuid, pk });
2020-07-09 00:56:30 +08:00
}
2020-05-14 19:47:28 +08:00
#[inline]
2020-07-09 02:16:59 +08:00
async fn get(&mut self, id: &str) -> Option<Peer> {
let p = self.map.read().unwrap().get(id).map(|x| x.clone());
2020-05-15 03:16:46 +08:00
if p.is_some() {
return p;
} else {
2020-07-09 02:16:59 +08:00
let id = id.to_owned();
let v = self.db.get(id.clone()).await;
2020-07-09 00:56:30 +08:00
if let Some(v) = super::SledAsync::deserialize::<PeerSerde>(&v) {
self.map.write().unwrap().insert(
2020-07-09 02:16:59 +08:00
id,
2020-07-09 00:56:30 +08:00
Peer {
2020-09-08 16:18:33 +08:00
uuid: v.uuid,
2020-07-09 00:56:30 +08:00
pk: v.pk,
..Default::default()
},
);
return Some(Peer::default());
2020-05-15 03:16:46 +08:00
}
}
None
}
#[inline]
2020-07-09 02:16:59 +08:00
fn is_in_memory(&self, id: &str) -> bool {
self.map.read().unwrap().contains_key(id)
2020-05-14 17:18:07 +08:00
}
}
2020-04-30 10:57:54 +08:00
const REG_TIMEOUT: i32 = 30_000;
2020-05-14 17:18:07 +08:00
type Sink = SplitSink<Framed<TcpStream, BytesCodec>, Bytes>;
2020-07-09 02:16:59 +08:00
type Sender = mpsc::UnboundedSender<(RendezvousMessage, SocketAddr)>;
2020-03-06 17:18:22 +08:00
2020-05-14 17:18:07 +08:00
#[derive(Clone)]
2020-03-06 17:18:22 +08:00
pub struct RendezvousServer {
2020-05-14 17:18:07 +08:00
tcp_punch: Arc<Mutex<HashMap<SocketAddr, Sink>>>,
2020-05-14 19:47:28 +08:00
pm: PeerMap,
2020-07-09 02:16:59 +08:00
tx: Sender,
2020-09-18 13:04:39 +08:00
relay_server: String,
2020-03-06 17:18:22 +08:00
}
impl RendezvousServer {
2020-09-18 13:04:39 +08:00
pub async fn start(addr: &str, relay_server: String) -> ResultType<()> {
2020-03-10 00:24:07 +08:00
let mut socket = FramedSocket::new(addr).await?;
2020-05-14 19:47:28 +08:00
let (tx, mut rx) = mpsc::unbounded_channel::<(RendezvousMessage, SocketAddr)>();
2020-03-07 00:37:23 +08:00
let mut rs = Self {
2020-05-11 12:57:55 +08:00
tcp_punch: Arc::new(Mutex::new(HashMap::new())),
2020-05-14 19:47:28 +08:00
pm: PeerMap::new()?,
tx: tx.clone(),
2020-09-18 13:04:39 +08:00
relay_server,
2020-03-06 17:18:22 +08:00
};
2020-05-14 17:18:07 +08:00
let mut listener = new_listener(addr, true).await?;
2020-03-12 22:06:09 +08:00
loop {
tokio::select! {
2020-05-14 19:47:28 +08:00
Some((msg, addr)) = rx.recv() => {
allow_err!(socket.send(&msg, addr).await);
2020-05-11 12:57:55 +08:00
}
2020-03-12 22:06:09 +08:00
Some(Ok((bytes, addr))) = socket.next() => {
2020-05-14 19:47:28 +08:00
allow_err!(rs.handle_msg(&bytes, addr, &mut socket).await);
2020-03-12 22:06:09 +08:00
}
2020-05-11 12:57:55 +08:00
Ok((stream, addr)) = listener.accept() => {
2020-03-12 22:06:09 +08:00
log::debug!("Tcp connection from {:?}", addr);
2020-05-11 12:57:55 +08:00
let (a, mut b) = Framed::new(stream, BytesCodec::new()).split();
let tcp_punch = rs.tcp_punch.clone();
tcp_punch.lock().unwrap().insert(addr, a);
2020-05-14 17:18:07 +08:00
let mut rs = rs.clone();
2020-05-11 12:57:55 +08:00
tokio::spawn(async move {
2020-09-18 00:47:15 +08:00
while let Ok(Some(Ok(bytes))) = timeout(30_000, b.next()).await {
2020-09-04 11:32:42 +08:00
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
2020-05-11 12:57:55 +08:00
match msg_in.union {
Some(rendezvous_message::Union::punch_hole_request(ph)) => {
2020-05-15 03:16:46 +08:00
allow_err!(rs.handle_tcp_punch_hole_request(addr, ph.id).await);
}
2020-09-17 18:55:35 +08:00
Some(rendezvous_message::Union::request_relay(mut rf)) => {
2020-09-18 00:47:15 +08:00
if let Some(peer) = rs.pm.map.read().unwrap().get(&rf.id).map(|x| x.clone()) {
let mut msg_out = RendezvousMessage::new();
rf.socket_addr = AddrMangle::encode(addr);
msg_out.set_request_relay(rf);
rs.tx.send((msg_out, peer.socket_addr)).ok();
2020-09-17 10:02:20 +08:00
}
}
2020-09-17 18:55:35 +08:00
Some(rendezvous_message::Union::request_relay_response(mut rfr)) => {
2020-09-17 10:02:20 +08:00
let addr_b = AddrMangle::decode(&rfr.socket_addr);
2020-09-17 18:55:35 +08:00
rfr.socket_addr = Default::default();
2020-09-18 00:47:15 +08:00
let mut msg_out = RendezvousMessage::new();
msg_out.set_request_relay_response(rfr);
let sender_b = rs.tcp_punch.lock().unwrap().remove(&addr_b);
2020-09-17 10:02:20 +08:00
if let Some(mut sender_b) = sender_b {
2020-09-18 00:47:15 +08:00
if let Ok(bytes) = msg_out.write_to_bytes() {
2020-09-17 10:02:20 +08:00
allow_err!(sender_b.send(Bytes::from(bytes)).await);
}
}
break;
}
Some(rendezvous_message::Union::punch_hole_sent(phs)) => {
2020-09-17 10:02:20 +08:00
allow_err!(rs.handle_hole_sent(phs, addr, None).await);
break;
}
Some(rendezvous_message::Union::local_addr(la)) => {
allow_err!(rs.handle_local_addr(&la, addr, None).await);
break;
2020-05-11 12:57:55 +08:00
}
2020-09-18 00:47:15 +08:00
_ => {
break;
}
2020-05-11 12:57:55 +08:00
}
2020-09-17 18:55:35 +08:00
} else {
break;
2020-05-11 12:57:55 +08:00
}
}
rs.tcp_punch.lock().unwrap().remove(&addr);
2020-05-11 12:57:55 +08:00
log::debug!("Tcp connection from {:?} closed", addr);
});
2020-03-12 22:06:09 +08:00
}
}
2020-03-06 17:18:22 +08:00
}
2020-03-07 00:37:23 +08:00
}
2020-05-14 19:47:28 +08:00
#[inline]
2020-05-14 17:18:07 +08:00
async fn handle_msg(
2020-03-07 22:45:22 +08:00
&mut self,
bytes: &BytesMut,
2020-03-07 00:37:23 +08:00
addr: SocketAddr,
socket: &mut FramedSocket,
2020-03-09 20:52:54 +08:00
) -> ResultType<()> {
2020-09-04 11:32:42 +08:00
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
2020-03-09 16:16:21 +08:00
match msg_in.union {
2020-04-21 23:49:31 +08:00
Some(rendezvous_message::Union::register_peer(rp)) => {
2020-03-12 19:25:37 +08:00
// B registered
if rp.id.len() > 0 {
log::debug!("New peer registered: {:?} {:?}", &rp.id, &addr);
2020-07-09 02:16:59 +08:00
self.update_addr(rp.id, addr, socket).await?;
2020-03-07 22:45:22 +08:00
}
2020-03-09 16:16:21 +08:00
}
2020-07-09 02:16:59 +08:00
Some(rendezvous_message::Union::register_pk(rk)) => {
2020-09-08 17:16:11 +08:00
if rk.uuid.is_empty() {
return Ok(());
}
2020-07-09 00:56:30 +08:00
let id = rk.id;
2020-07-09 02:16:59 +08:00
let mut res = register_pk_response::Result::OK;
if let Some(peer) = self.pm.get(&id).await {
2020-09-08 17:16:11 +08:00
if !peer.uuid.is_empty() && peer.uuid != rk.uuid {
log::warn!(
"Peer {} uuid mismatch: {:?} vs {:?}",
id,
rk.uuid,
peer.uuid
);
2020-09-08 16:18:33 +08:00
res = register_pk_response::Result::UUID_MISMATCH;
2020-09-08 17:16:11 +08:00
} else if peer.uuid.is_empty() || peer.pk != rk.pk {
2020-09-08 16:18:33 +08:00
self.pm.update_pk(id, addr, rk.uuid, rk.pk);
2020-07-09 00:56:30 +08:00
}
2020-07-09 02:16:59 +08:00
} else {
2020-09-08 16:18:33 +08:00
self.pm.update_pk(id, addr, rk.uuid, rk.pk);
2020-07-09 00:56:30 +08:00
}
2020-07-09 02:16:59 +08:00
let mut msg_out = RendezvousMessage::new();
msg_out.set_register_pk_response(RegisterPkResponse {
result: res.into(),
..Default::default()
});
socket.send(&msg_out, addr).await?
2020-07-09 00:56:30 +08:00
}
2020-04-21 23:49:31 +08:00
Some(rendezvous_message::Union::punch_hole_request(ph)) => {
2020-05-15 03:16:46 +08:00
let id = ph.id;
if self.pm.is_in_memory(&id) {
self.handle_udp_punch_hole_request(addr, id).await?;
} else {
2020-06-21 14:31:52 +08:00
// not in memory, fetch from db with spawn in case blocking me
2020-05-15 03:16:46 +08:00
let mut me = self.clone();
tokio::spawn(async move {
allow_err!(me.handle_udp_punch_hole_request(addr, id).await);
});
}
2020-03-07 22:45:22 +08:00
}
2020-04-21 23:49:31 +08:00
Some(rendezvous_message::Union::punch_hole_sent(phs)) => {
2020-09-17 10:02:20 +08:00
self.handle_hole_sent(phs, addr, Some(socket)).await?;
2020-03-09 16:16:21 +08:00
}
2020-04-21 23:49:31 +08:00
Some(rendezvous_message::Union::local_addr(la)) => {
self.handle_local_addr(&la, addr, Some(socket)).await?;
2020-03-12 19:25:37 +08:00
}
2020-06-21 14:31:52 +08:00
Some(rendezvous_message::Union::system_info(info)) => {
2020-07-09 00:56:30 +08:00
log::info!("{}", info.value);
2020-06-21 14:31:52 +08:00
}
2020-03-09 16:16:21 +08:00
_ => {}
2020-03-07 22:45:22 +08:00
}
2020-03-07 00:37:23 +08:00
}
Ok(())
2020-03-06 17:18:22 +08:00
}
2020-05-11 12:57:55 +08:00
2020-07-09 02:16:59 +08:00
#[inline]
async fn update_addr(
&mut self,
id: String,
socket_addr: SocketAddr,
socket: &mut FramedSocket,
) -> ResultType<()> {
let mut lock = self.pm.map.write().unwrap();
let last_reg_time = Instant::now();
if let Some(old) = lock.get_mut(&id) {
old.socket_addr = socket_addr;
old.last_reg_time = last_reg_time;
let request_pk = old.pk.is_empty();
drop(lock);
let mut msg_out = RendezvousMessage::new();
msg_out.set_register_peer_response(RegisterPeerResponse {
request_pk,
..Default::default()
});
socket.send(&msg_out, socket_addr).await?;
} else {
drop(lock);
let mut pm = self.pm.clone();
let tx = self.tx.clone();
tokio::spawn(async move {
let v = pm.db.get(id.clone()).await;
2020-09-08 16:18:33 +08:00
let (uuid, pk) = {
2020-07-09 02:16:59 +08:00
if let Some(v) = super::SledAsync::deserialize::<PeerSerde>(&v) {
2020-09-08 16:18:33 +08:00
(v.uuid, v.pk)
2020-07-09 02:16:59 +08:00
} else {
2020-09-08 16:18:33 +08:00
(Vec::new(), Vec::new())
2020-07-09 02:16:59 +08:00
}
};
let mut msg_out = RendezvousMessage::new();
msg_out.set_register_peer_response(RegisterPeerResponse {
request_pk: pk.is_empty(),
..Default::default()
});
tx.send((msg_out, socket_addr)).ok();
pm.map.write().unwrap().insert(
id,
Peer {
socket_addr,
last_reg_time,
2020-09-08 16:18:33 +08:00
uuid,
2020-07-09 02:16:59 +08:00
pk,
},
);
});
}
Ok(())
}
2020-05-14 19:47:28 +08:00
#[inline]
async fn handle_hole_sent<'a>(
&mut self,
2020-09-17 10:02:20 +08:00
phs: PunchHoleSent,
addr: SocketAddr,
socket: Option<&'a mut FramedSocket>,
) -> ResultType<()> {
// punch hole sent from B, tell A that B is ready to be connected
let addr_a = AddrMangle::decode(&phs.socket_addr);
log::debug!(
"{} punch hole response to {:?} from {:?}",
if socket.is_none() { "TCP" } else { "UDP" },
&addr_a,
&addr
);
let mut msg_out = RendezvousMessage::new();
2020-07-09 02:28:36 +08:00
let pk = match self.pm.get(&phs.id).await {
Some(peer) => peer.pk,
_ => Vec::new(),
};
2020-09-18 13:04:39 +08:00
let mut relay_server = phs.relay_server;
if relay_server.is_empty() {
relay_server = self.relay_server.clone();
}
msg_out.set_punch_hole_response(PunchHoleResponse {
socket_addr: AddrMangle::encode(addr),
2020-07-09 02:28:36 +08:00
pk,
2020-09-17 18:55:35 +08:00
relay_server,
..Default::default()
});
if let Some(socket) = socket {
socket.send(&msg_out, addr_a).await?;
} else {
2020-05-14 19:47:28 +08:00
self.send_to_tcp(&msg_out, addr_a).await;
}
Ok(())
}
2020-05-14 19:47:28 +08:00
#[inline]
async fn handle_local_addr<'a>(
&mut self,
la: &LocalAddr,
addr: SocketAddr,
socket: Option<&'a mut FramedSocket>,
) -> ResultType<()> {
2020-09-17 18:55:35 +08:00
// relay local addrs of B to A
let addr_a = AddrMangle::decode(&la.socket_addr);
log::debug!(
"{} local addrs response to {:?} from {:?}",
if socket.is_none() { "TCP" } else { "UDP" },
&addr_a,
&addr
);
let mut msg_out = RendezvousMessage::new();
msg_out.set_punch_hole_response(PunchHoleResponse {
socket_addr: la.local_addr.clone(),
..Default::default()
});
if let Some(socket) = socket {
socket.send(&msg_out, addr_a).await?;
} else {
2020-05-14 19:47:28 +08:00
self.send_to_tcp(&msg_out, addr_a).await;
}
Ok(())
}
2020-05-14 19:47:28 +08:00
#[inline]
2020-05-11 12:57:55 +08:00
async fn handle_punch_hole_request(
&mut self,
addr: SocketAddr,
2020-05-15 03:16:46 +08:00
id: String,
2020-05-14 19:47:28 +08:00
) -> ResultType<(RendezvousMessage, Option<SocketAddr>)> {
2020-09-17 18:55:35 +08:00
// punch hole request from A, relay to B,
2020-05-11 12:57:55 +08:00
// check if in same intranet first,
// fetch local addrs if in same intranet.
// because punch hole won't work if in the same intranet,
// all routers will drop such self-connections.
2020-07-09 02:16:59 +08:00
if let Some(peer) = self.pm.get(&id).await {
2020-05-11 12:57:55 +08:00
if peer.last_reg_time.elapsed().as_millis() as i32 >= REG_TIMEOUT {
let mut msg_out = RendezvousMessage::new();
msg_out.set_punch_hole_response(PunchHoleResponse {
failure: punch_hole_response::Failure::OFFLINE.into(),
..Default::default()
});
2020-05-14 19:47:28 +08:00
return Ok((msg_out, None));
2020-05-11 12:57:55 +08:00
}
let mut msg_out = RendezvousMessage::new();
let same_intranet = match peer.socket_addr {
SocketAddr::V4(a) => match addr {
SocketAddr::V4(b) => a.ip() == b.ip(),
_ => false,
},
SocketAddr::V6(a) => match addr {
SocketAddr::V6(b) => a.ip() == b.ip(),
_ => false,
},
};
let socket_addr = AddrMangle::encode(addr);
if same_intranet {
log::debug!(
"Fetch local addr {:?} {:?} request from {:?}",
id,
&peer.socket_addr,
&addr
);
msg_out.set_fetch_local_addr(FetchLocalAddr {
socket_addr,
..Default::default()
});
} else {
log::debug!(
"Punch hole {:?} {:?} request from {:?}",
id,
&peer.socket_addr,
&addr
);
msg_out.set_punch_hole(PunchHole {
socket_addr,
..Default::default()
});
}
2020-05-14 19:47:28 +08:00
return Ok((msg_out, Some(peer.socket_addr)));
2020-05-11 12:57:55 +08:00
} else {
let mut msg_out = RendezvousMessage::new();
msg_out.set_punch_hole_response(PunchHoleResponse {
failure: punch_hole_response::Failure::ID_NOT_EXIST.into(),
..Default::default()
});
2020-05-14 19:47:28 +08:00
return Ok((msg_out, None));
2020-05-11 12:57:55 +08:00
}
}
2020-05-14 19:47:28 +08:00
#[inline]
async fn send_to_tcp(&mut self, msg: &RendezvousMessage, addr: SocketAddr) {
2020-05-11 12:57:55 +08:00
let tcp = self.tcp_punch.lock().unwrap().remove(&addr);
if let Some(mut tcp) = tcp {
if let Ok(bytes) = msg.write_to_bytes() {
tokio::spawn(async move {
allow_err!(tcp.send(Bytes::from(bytes)).await);
});
}
}
2020-05-14 19:47:28 +08:00
}
#[inline]
async fn send_to_tcp_sync(
&mut self,
msg: &RendezvousMessage,
addr: SocketAddr,
) -> ResultType<()> {
let tcp = self.tcp_punch.lock().unwrap().remove(&addr);
if let Some(mut tcp) = tcp {
if let Ok(bytes) = msg.write_to_bytes() {
tcp.send(Bytes::from(bytes)).await?;
}
}
Ok(())
}
#[inline]
async fn handle_tcp_punch_hole_request(
&mut self,
addr: SocketAddr,
2020-05-15 03:16:46 +08:00
id: String,
2020-05-14 19:47:28 +08:00
) -> ResultType<()> {
let (msg, to_addr) = self.handle_punch_hole_request(addr, id).await?;
if let Some(addr) = to_addr {
self.tx.send((msg, addr))?;
} else {
self.send_to_tcp_sync(&msg, addr).await?;
}
Ok(())
}
#[inline]
async fn handle_udp_punch_hole_request(
&mut self,
addr: SocketAddr,
2020-05-15 03:16:46 +08:00
id: String,
2020-05-14 19:47:28 +08:00
) -> ResultType<()> {
let (msg, to_addr) = self.handle_punch_hole_request(addr, id).await?;
self.tx.send((
msg,
match to_addr {
Some(addr) => addr,
None => addr,
},
))?;
2020-05-11 12:57:55 +08:00
Ok(())
}
}