rustdesk-server/src/rendezvous_server.rs

664 lines
25 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-10-31 11:25:53 +08:00
protobuf::{Message as _, MessageField},
2020-05-11 12:57:55 +08:00
rendezvous_proto::*,
2020-09-27 22:20:42 +08:00
tcp::{new_listener, FramedStream},
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-10-31 14:33:25 +08:00
pub const LICENSE_KEY: &'static str = "";
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-10-31 14:33:25 +08:00
static mut ROTATION_RELAY_SERVER: usize = 0;
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-10-31 14:33:25 +08:00
relay_servers: Vec<String>,
2020-09-18 17:07:17 +08:00
serial: i32,
rendezvous_servers: Vec<String>,
2020-09-21 22:56:38 +08:00
version: String,
software_url: String,
2020-03-06 17:18:22 +08:00
}
impl RendezvousServer {
2020-09-18 17:07:17 +08:00
pub async fn start(
addr: &str,
2020-09-27 22:20:42 +08:00
addr2: &str,
2020-10-31 14:33:25 +08:00
relay_servers: Vec<String>,
2020-09-18 17:07:17 +08:00
serial: i32,
rendezvous_servers: Vec<String>,
2020-09-21 22:56:38 +08:00
software_url: String,
2020-09-18 17:07:17 +08:00
) -> 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-09-21 23:25:39 +08:00
let version = hbb_common::get_version_from_url(&software_url);
if !version.is_empty() {
log::info!("software_url: {}, version: {}", software_url, version);
}
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-10-31 14:33:25 +08:00
relay_servers,
2020-09-18 17:07:17 +08:00
serial,
rendezvous_servers,
2020-09-21 23:25:39 +08:00
version,
2020-09-21 22:56:38 +08:00
software_url,
2020-03-06 17:18:22 +08:00
};
2020-09-18 17:27:23 +08:00
let mut listener = new_listener(addr, false).await?;
2020-09-27 22:20:42 +08:00
let mut listener2 = new_listener(addr2, false).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-09-27 22:20:42 +08:00
Ok((stream, addr)) = listener2.accept() => {
let stream = FramedStream::from(stream);
tokio::spawn(async move {
let mut stream = stream;
if let Some(Ok(bytes)) = stream.next_timeout(30_000).await {
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
if let Some(rendezvous_message::Union::test_nat_request(_)) = msg_in.union {
let mut msg_out = RendezvousMessage::new();
msg_out.set_test_nat_response(TestNatResponse {
port: addr.port() as _,
..Default::default()
});
stream.send(&msg_out).await.ok();
}
}
}
});
}
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();
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-25 17:57:06 +08:00
let mut sender = Some(a);
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-09-27 13:53:29 +08:00
// there maybe several attempt, so sender can be none
2020-09-25 17:57:06 +08:00
if let Some(sender) = sender.take() {
tcp_punch.lock().unwrap().insert(addr, sender);
}
allow_err!(rs.handle_tcp_punch_hole_request(addr, ph).await);
}
2020-09-17 18:55:35 +08:00
Some(rendezvous_message::Union::request_relay(mut rf)) => {
2020-09-27 13:53:29 +08:00
// there maybe several attempt, so sender can be none
2020-09-25 17:57:06 +08:00
if let Some(sender) = sender.take() {
tcp_punch.lock().unwrap().insert(addr, sender);
}
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
}
}
Some(rendezvous_message::Union::relay_response(mut rr)) => {
let addr_b = AddrMangle::decode(&rr.socket_addr);
rr.socket_addr = Default::default();
let id = rr.get_id();
if !id.is_empty() {
if let Some(peer) = rs.pm.get(&id).await {
rr.set_pk(peer.pk.clone());
}
}
2020-09-18 00:47:15 +08:00
let mut msg_out = RendezvousMessage::new();
msg_out.set_relay_response(rr);
2020-09-25 17:57:06 +08:00
allow_err!(rs.send_to_tcp_sync(&msg_out, addr_b).await);
2020-09-17 10:02:20 +08:00
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-10-31 11:25:53 +08:00
Some(rendezvous_message::Union::test_nat_request(tar)) => {
2020-09-25 17:57:06 +08:00
let mut msg_out = RendezvousMessage::new();
2020-10-31 11:25:53 +08:00
let mut res = TestNatResponse {
2020-09-25 17:57:06 +08:00
port: addr.port() as _,
..Default::default()
2020-10-31 14:33:25 +08:00
};
2020-10-31 11:25:53 +08:00
if rs.serial > tar.serial {
let mut cu = ConfigUpdate::new();
cu.serial = rs.serial;
cu.rendezvous_servers = rs.rendezvous_servers.clone();
res.cu = MessageField::from_option(Some(cu));
}
msg_out.set_test_nat_response(res);
2020-09-25 17:57:06 +08:00
if let Some(tcp) = sender.as_mut() {
if let Ok(bytes) = msg_out.write_to_bytes() {
allow_err!(tcp.send(Bytes::from(bytes)).await);
}
}
break;
}
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
}
}
2020-09-25 17:57:06 +08:00
if sender.is_none() {
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-09-18 17:43:21 +08:00
if self.serial > rp.serial {
2020-09-18 17:07:17 +08:00
let mut msg_out = RendezvousMessage::new();
msg_out.set_configure_update(ConfigUpdate {
2020-09-18 17:07:17 +08:00
serial: self.serial,
rendezvous_servers: self.rendezvous_servers.clone(),
..Default::default()
});
socket.send(&msg_out, addr).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)) => {
if self.pm.is_in_memory(&ph.id) {
self.handle_udp_punch_hole_request(addr, ph).await?;
2020-05-15 03:16:46 +08:00
} 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, ph).await);
2020-05-15 03:16:46 +08:00
});
}
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
}
Some(rendezvous_message::Union::configure_update(mut cu)) => {
if addr.ip() == std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1))
&& cu.serial > self.serial
{
self.serial = cu.serial;
self.rendezvous_servers = cu
.rendezvous_servers
.drain(..)
2020-10-31 14:33:25 +08:00
.filter(|x| {
!x.is_empty()
&& test_if_valid_server(x, "rendezvous-server").is_ok()
})
.collect();
log::info!(
"configure updated: serial={} rendezvous-servers={:?}",
self.serial,
self.rendezvous_servers
);
2020-09-18 17:22:11 +08:00
}
}
2020-09-21 22:56:38 +08:00
Some(rendezvous_message::Union::software_update(su)) => {
if !self.version.is_empty() && su.url != self.version {
let mut msg_out = RendezvousMessage::new();
msg_out.set_software_update(SoftwareUpdate {
url: self.software_url.clone(),
..Default::default()
});
socket.send(&msg_out, addr).await?;
}
}
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-26 10:57:01 +08:00
let mut p = PunchHoleResponse {
socket_addr: AddrMangle::encode(addr),
2020-07-09 02:28:36 +08:00
pk,
relay_server: phs.relay_server.clone(),
..Default::default()
2020-09-26 10:57:01 +08:00
};
if let Ok(t) = phs.nat_type.enum_value() {
p.set_nat_type(t);
}
msg_out.set_punch_hole_response(p);
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();
2020-09-26 10:57:01 +08:00
let mut p = PunchHoleResponse {
socket_addr: la.local_addr.clone(),
relay_server: la.relay_server,
..Default::default()
2020-09-26 10:57:01 +08:00
};
p.set_is_local(true);
msg_out.set_punch_hole_response(p);
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,
ph: PunchHoleRequest,
2020-05-14 19:47:28 +08:00
) -> ResultType<(RendezvousMessage, Option<SocketAddr>)> {
2020-10-31 14:33:25 +08:00
if ph.licence_key != LICENSE_KEY {
let mut msg_out = RendezvousMessage::new();
msg_out.set_punch_hole_response(PunchHoleResponse {
failure: punch_hole_response::Failure::LICENCE_MISMATCH.into(),
..Default::default()
});
return Ok((msg_out, None));
}
let id = ph.id;
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
);
2020-10-31 14:33:25 +08:00
let i = unsafe {
ROTATION_RELAY_SERVER += 1;
ROTATION_RELAY_SERVER % self.relay_servers.len()
};
2020-05-11 12:57:55 +08:00
msg_out.set_fetch_local_addr(FetchLocalAddr {
socket_addr,
2020-10-31 14:33:25 +08:00
relay_server: self.relay_servers[i].clone(),
2020-05-11 12:57:55 +08:00
..Default::default()
});
} else {
log::debug!(
"Punch hole {:?} {:?} request from {:?}",
id,
&peer.socket_addr,
&addr
);
2020-10-31 14:33:25 +08:00
let i = unsafe {
ROTATION_RELAY_SERVER += 1;
ROTATION_RELAY_SERVER % self.relay_servers.len()
};
2020-05-11 12:57:55 +08:00
msg_out.set_punch_hole(PunchHole {
socket_addr,
nat_type: ph.nat_type,
2020-10-31 14:33:25 +08:00
relay_server: self.relay_servers[i].clone(),
2020-05-11 12:57:55 +08:00
..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,
ph: PunchHoleRequest,
2020-05-14 19:47:28 +08:00
) -> ResultType<()> {
let (msg, to_addr) = self.handle_punch_hole_request(addr, ph).await?;
2020-05-14 19:47:28 +08:00
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,
ph: PunchHoleRequest,
2020-05-14 19:47:28 +08:00
) -> ResultType<()> {
let (msg, to_addr) = self.handle_punch_hole_request(addr, ph).await?;
2020-05-14 19:47:28 +08:00
self.tx.send((
msg,
match to_addr {
Some(addr) => addr,
None => addr,
},
))?;
2020-05-11 12:57:55 +08:00
Ok(())
}
}
2020-09-20 20:02:42 +08:00
2020-10-31 14:33:25 +08:00
pub fn test_if_valid_server(host: &str, name: &str) -> ResultType<SocketAddr> {
let res = if host.contains(":") {
2020-09-21 22:56:38 +08:00
hbb_common::to_socket_addr(host)
2020-09-20 20:02:42 +08:00
} else {
2020-09-21 22:56:38 +08:00
hbb_common::to_socket_addr(&format!("{}:{}", host, 0))
2020-10-31 14:33:25 +08:00
};
if res.is_err() {
log::error!("Invalid {} {}: {:?}", name, host, res);
2020-09-20 20:02:42 +08:00
}
2020-10-31 14:33:25 +08:00
res
2020-09-20 20:02:42 +08:00
}