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::*,
|
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
|
|
|
}
|
|
|
|
|
2020-05-15 17:42:29 +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 17:42:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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(),
|
2020-05-15 17:42:29 +08:00
|
|
|
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()
|
|
|
|
},
|
|
|
|
);
|
2020-05-15 17:42:29 +08:00
|
|
|
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-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-09-18 17:07:17 +08:00
|
|
|
relay_server: String,
|
|
|
|
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-09-18 13:04:39 +08:00
|
|
|
relay_server,
|
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);
|
|
|
|
}
|
2020-09-27 08:54:43 +08:00
|
|
|
allow_err!(rs.handle_tcp_punch_hole_request(addr, ph).await);
|
2020-05-11 15:47:13 +08:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
}
|
2020-09-27 08:54:43 +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();
|
2020-09-27 08:54:43 +08:00
|
|
|
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;
|
|
|
|
}
|
2020-05-11 15:47:13 +08:00
|
|
|
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);
|
2020-05-11 15:47:13 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
Some(rendezvous_message::Union::local_addr(la)) => {
|
2020-09-21 15:13:14 +08:00
|
|
|
allow_err!(rs.handle_local_addr(la, addr, None).await);
|
2020-05-11 15:47:13 +08:00
|
|
|
break;
|
2020-05-11 12:57:55 +08:00
|
|
|
}
|
2020-09-25 17:57:06 +08:00
|
|
|
Some(rendezvous_message::Union::test_nat_request(_)) => {
|
|
|
|
let mut msg_out = RendezvousMessage::new();
|
|
|
|
msg_out.set_test_nat_response(TestNatResponse {
|
|
|
|
port: addr.port() as _,
|
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
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-11 02:20:45 +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
|
2020-04-17 17:04:56 +08:00
|
|
|
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();
|
2020-09-21 15:13:14 +08:00
|
|
|
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)) => {
|
2020-09-27 08:54:43 +08:00
|
|
|
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 {
|
2020-09-27 08:54:43 +08:00
|
|
|
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)) => {
|
2020-09-21 15:13:14 +08:00
|
|
|
self.handle_local_addr(la, addr, Some(socket)).await?;
|
2020-03-12 19:25:37 +08:00
|
|
|
}
|
2020-09-21 15:13:14 +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(..)
|
|
|
|
.filter(|x| test_if_valid_server(x).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 15:13:14 +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]
|
2020-05-11 15:47:13 +08:00
|
|
|
async fn handle_hole_sent<'a>(
|
|
|
|
&mut self,
|
2020-09-17 10:02:20 +08:00
|
|
|
phs: PunchHoleSent,
|
2020-05-11 15:47:13 +08:00
|
|
|
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 {
|
2020-05-11 15:47:13 +08:00
|
|
|
socket_addr: AddrMangle::encode(addr),
|
2020-07-09 02:28:36 +08:00
|
|
|
pk,
|
2020-09-27 08:54:43 +08:00
|
|
|
relay_server: phs.relay_server.clone(),
|
2020-05-11 15:47:13 +08:00
|
|
|
..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);
|
2020-05-11 15:47:13 +08:00
|
|
|
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;
|
2020-05-11 15:47:13 +08:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-05-14 19:47:28 +08:00
|
|
|
#[inline]
|
2020-05-11 15:47:13 +08:00
|
|
|
async fn handle_local_addr<'a>(
|
|
|
|
&mut self,
|
2020-09-21 15:13:14 +08:00
|
|
|
la: LocalAddr,
|
2020-05-11 15:47:13 +08:00
|
|
|
addr: SocketAddr,
|
|
|
|
socket: Option<&'a mut FramedSocket>,
|
|
|
|
) -> ResultType<()> {
|
2020-09-17 18:55:35 +08:00
|
|
|
// relay local addrs of B to A
|
2020-05-11 15:47:13 +08:00
|
|
|
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 {
|
2020-05-11 15:47:13 +08:00
|
|
|
socket_addr: la.local_addr.clone(),
|
2020-09-27 08:54:43 +08:00
|
|
|
relay_server: la.relay_server,
|
2020-05-11 15:47:13 +08:00
|
|
|
..Default::default()
|
2020-09-26 10:57:01 +08:00
|
|
|
};
|
|
|
|
p.set_is_local(true);
|
|
|
|
msg_out.set_punch_hole_response(p);
|
2020-05-11 15:47:13 +08:00
|
|
|
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;
|
2020-05-11 15:47:13 +08:00
|
|
|
}
|
|
|
|
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-09-27 08:54:43 +08:00
|
|
|
ph: PunchHoleRequest,
|
2020-05-14 19:47:28 +08:00
|
|
|
) -> ResultType<(RendezvousMessage, Option<SocketAddr>)> {
|
2020-09-27 08:54:43 +08:00
|
|
|
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
|
|
|
|
);
|
|
|
|
msg_out.set_fetch_local_addr(FetchLocalAddr {
|
|
|
|
socket_addr,
|
2020-09-27 08:54:43 +08:00
|
|
|
relay_server: self.relay_server.clone(),
|
2020-05-11 12:57:55 +08:00
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
log::debug!(
|
|
|
|
"Punch hole {:?} {:?} request from {:?}",
|
|
|
|
id,
|
|
|
|
&peer.socket_addr,
|
|
|
|
&addr
|
|
|
|
);
|
|
|
|
msg_out.set_punch_hole(PunchHole {
|
|
|
|
socket_addr,
|
2020-09-27 08:54:43 +08:00
|
|
|
nat_type: ph.nat_type,
|
|
|
|
relay_server: self.relay_server.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,
|
2020-09-27 08:54:43 +08:00
|
|
|
ph: PunchHoleRequest,
|
2020-05-14 19:47:28 +08:00
|
|
|
) -> ResultType<()> {
|
2020-09-27 08:54:43 +08:00
|
|
|
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,
|
2020-09-27 08:54:43 +08:00
|
|
|
ph: PunchHoleRequest,
|
2020-05-14 19:47:28 +08:00
|
|
|
) -> ResultType<()> {
|
2020-09-27 08:54:43 +08:00
|
|
|
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
|
|
|
|
|
|
|
pub fn test_if_valid_server(host: &str) -> ResultType<SocketAddr> {
|
|
|
|
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-09-20 20:02:42 +08:00
|
|
|
}
|
|
|
|
}
|