lan discovery almost done

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2021-12-21 00:10:14 +08:00
parent 5682b088de
commit d00352f4e4
9 changed files with 93 additions and 47 deletions

View File

@ -4,9 +4,10 @@ package discovery;
import "base_proto.proto"; import "base_proto.proto";
message Discovery { message Discovery {
base.PeerInfo peer = 1; string id = 1;
base.PeerInfo peer = 2;
/// response port for current listening port(udp for now) /// response port for current listening port(udp for now)
int32 port = 2; int32 port = 3;
} }
message DiscoveryBack { message DiscoveryBack {

View File

@ -14,6 +14,7 @@ async fn lan_discover(port: u16, port_back: u16) {
..Default::default() ..Default::default()
}; };
let client = DiscoveryClient::create(DiscoveryProto { let client = DiscoveryClient::create(DiscoveryProto {
id: "client id".to_owned(),
peer: protobuf::MessageField::from_option(Some(peer)), peer: protobuf::MessageField::from_option(Some(peer)),
port: port_back as i32, port: port_back as i32,
..Default::default() ..Default::default()

View File

@ -32,7 +32,7 @@ impl DiscoveryClient {
log::trace!("succeeded to bind {} for discovery client", addr); log::trace!("succeeded to bind {} for discovery client", addr);
socket.set_broadcast(true)?; socket.set_broadcast(true)?;
log::info!("Broadcast mode set to ON"); log::trace!("Broadcast mode set to ON");
let send_data = make_send_data(CMD_DISCOVERY, &info)?; let send_data = make_send_data(CMD_DISCOVERY, &info)?;
Ok(Self { socket, send_data }) Ok(Self { socket, send_data })
@ -47,6 +47,7 @@ impl DiscoveryClient {
pub struct HandlerDiscovery { pub struct HandlerDiscovery {
get_allow: Option<fn() -> bool>, get_allow: Option<fn() -> bool>,
id: String,
send_data: Vec<u8>, send_data: Vec<u8>,
} }
@ -55,6 +56,7 @@ impl HandlerDiscovery {
let send_data = make_send_data(CMD_DISCOVERY_BACK, &self_info).unwrap(); let send_data = make_send_data(CMD_DISCOVERY_BACK, &self_info).unwrap();
Self { Self {
get_allow, get_allow,
id: self_info.id,
send_data, send_data,
} }
} }
@ -63,11 +65,13 @@ impl HandlerDiscovery {
#[async_trait] #[async_trait]
impl crate::Handler<UdpRequest> for HandlerDiscovery { impl crate::Handler<UdpRequest> for HandlerDiscovery {
async fn call(&self, request: UdpRequest) -> ResultType<()> { async fn call(&self, request: UdpRequest) -> ResultType<()> {
log::trace!("received discover query from {}", request.addr);
let discovery = DiscoveryProto::parse_from_bytes(&request.data)?; let discovery = DiscoveryProto::parse_from_bytes(&request.data)?;
if discovery.id == self.id {
return Ok(());
}
let peer = discovery.peer.as_ref().take().unwrap(); let peer = discovery.peer.as_ref().take().unwrap();
log::debug!( log::trace!(
"received discovery query from {} {}", "received discovery query from {} {}",
peer.username, peer.username,
peer.hostname peer.hostname
@ -75,12 +79,12 @@ impl crate::Handler<UdpRequest> for HandlerDiscovery {
let allowed = self.get_allow.map_or(false, |f| f()); let allowed = self.get_allow.map_or(false, |f| f());
if !allowed { if !allowed {
log::info!( // log::info!(
"received discovery query from {} {} {}, but discovery is not allowed", // "received discovery query from {} {} {}, but discovery is not allowed",
request.addr, // request.addr,
peer.hostname, // peer.hostname,
peer.username // peer.username
); // );
return Ok(()); return Ok(());
} }
@ -89,7 +93,7 @@ impl crate::Handler<UdpRequest> for HandlerDiscovery {
let mut peer_addr = request.addr; let mut peer_addr = request.addr;
peer_addr.set_port(discovery.port as u16); peer_addr.set_port(discovery.port as u16);
log::debug!("send self peer info to {}", peer_addr); log::trace!("send self peer info to {}", peer_addr);
let send_len = self.send_data.len(); let send_len = self.send_data.len();
let mut cur_len = 0usize; let mut cur_len = 0usize;

View File

@ -64,7 +64,6 @@ impl Server {
break; break;
} }
n = server.next() => { n = server.next() => {
log::info!("received message");
let handlers = handlers.clone(); let handlers = handlers.clone();
let rt = rt.clone(); let rt = rt.clone();
match n { match n {
@ -76,24 +75,24 @@ impl Server {
match handlers.get(&cmd) { match handlers.get(&cmd) {
Some(h) => { Some(h) => {
let request = UdpRequest {data: data[p+1..].to_vec(), addr}; let request = UdpRequest {data: data[p+1..].to_vec(), addr};
if let Err(e) = h.call(request).await { if let Err(_e) = h.call(request).await {
log::error!("handle {:?} failed, {}", cmd, e); // log::error!("handle {:?} failed, {}", cmd, e);
} }
} }
None => { None => {
log::warn!("no handler for {:?}", &cmd); // log::warn!("no handler for {:?}", &cmd);
} }
} }
}); });
} }
None => { None => {
log::error!("failed to parse command token"); // log::error!("failed to parse command token");
} }
} }
} }
Some(Err(e)) => { Some(Err(_e)) => {
log::error!("recv error: {}", e) // log::error!("recv error: {}", e)
} }
None => { None => {
log::error!("should never reach here"); log::error!("should never reach here");
@ -139,11 +138,12 @@ impl UdpHandlers {
/// ```rust /// ```rust
/// extern crate socket_cs; /// extern crate socket_cs;
/// use socket_cs::{ResultType, udp::{UdpHandlers, UdpRequest}}; /// use socket_cs::{ResultType, udp::{UdpHandlers, UdpRequest}};
/// use async_trait::async_trait;
/// ///
/// struct SimpleHandler; /// struct SimpleHandler;
/// ///
/// #[async_trait] /// #[async_trait]
/// impl crate::Handler<UdpRequest> for SimpleHandler { /// impl socket_cs::Handler<UdpRequest> for SimpleHandler {
/// async fn call(&self, _: UdpRequest) -> ResultType<()> { /// async fn call(&self, _: UdpRequest) -> ResultType<()> {
/// Ok(()) /// Ok(())
/// } /// }

View File

@ -389,6 +389,22 @@ pub fn get_id() -> String {
} }
} }
pub async fn get_id_async() -> String {
if let Ok(Some(v)) = get_config_async("id", 1_000).await {
// update salt also, so that next time reinstallation not causing first-time auto-login failure
if let Ok(Some(v2)) = get_config_async("salt", 1_000).await {
Config::set_salt(&v2);
}
if v != Config::get_id() {
Config::set_key_confirmed(false);
Config::set_id(&v);
}
v
} else {
Config::get_id()
}
}
pub fn get_password() -> String { pub fn get_password() -> String {
if let Ok(Some(v)) = get_config("password") { if let Ok(Some(v)) = get_config("password") {
Config::set_password(&v); Config::set_password(&v);

View File

@ -28,7 +28,7 @@ mod connection;
pub mod input_service; pub mod input_service;
mod service; mod service;
mod video_service; mod video_service;
mod udp; pub mod udp;
use hbb_common::tcp::new_listener; use hbb_common::tcp::new_listener;

View File

@ -25,23 +25,20 @@ fn get_peer_info() -> PeerInfo {
} }
} }
mod discovery { pub mod discovery {
use super::get_peer_info; use super::get_peer_info;
use crate::ipc; use crate::ipc;
use hbb_common::{ use hbb_common::{
base_proto::PeerInfo, config::{Config, PeerConfig, PeerInfoSerde, SERVER_UDP_PORT},
config::{PeerConfig, PeerInfoSerde},
discovery_proto::{Discovery as DiscoveryProto, DiscoveryBack as DiscoveryBackProto}, discovery_proto::{Discovery as DiscoveryProto, DiscoveryBack as DiscoveryBackProto},
log, protobuf, log, protobuf, tokio, ResultType,
tokio::runtime::Runtime,
ResultType,
}; };
use socket_cs::{discovery::*, udp::UdpHandlers}; use socket_cs::{discovery::*, udp::UdpHandlers};
fn get_discovery_back_info() -> DiscoveryBackProto { async fn get_discovery_back_info() -> DiscoveryBackProto {
let peer = get_peer_info(); let peer = get_peer_info();
DiscoveryBackProto { DiscoveryBackProto {
id: ipc::get_id(), id: ipc::get_id_async().await,
peer: protobuf::MessageField::from_option(Some(peer)), peer: protobuf::MessageField::from_option(Some(peer)),
..Default::default() ..Default::default()
} }
@ -59,35 +56,52 @@ mod discovery {
config.info = serde; config.info = serde;
config.store(info.id.as_str()); config.store(info.id.as_str());
let rt = match Runtime::new() { #[tokio::main(flavor = "current_thread")]
Ok(r) => r,
Err(e) => {
log::error!("Failed to notify index window, {}", e);
return;
}
};
async fn notify_index_window() -> ResultType<()> { async fn notify_index_window() -> ResultType<()> {
let ms_timeout = 1000; let ms_timeout = 300;
let mut c = ipc::connect(ms_timeout, "_index").await?; let mut c = ipc::connect(ms_timeout, "_index").await?;
c.send(&ipc::Data::SessionsUpdated).await?; c.send(&ipc::Data::SessionsUpdated).await?;
Ok(()) Ok(())
} }
rt.block_on(async move { std::thread::spawn(move || {
if let Err(e) = notify_index_window().await { if let Err(e) = notify_index_window() {
log::error!("Failed to notify index window, {}", e); log::error!("Failed to notify index window, {}", e);
} }
}); });
} }
// pub(crate) fn lan_discover(); pub fn launch_lan_discover() {
std::thread::spawn(move || {
if let Err(e) = lan_discover() {
log::error!("Failed to lauch lan discover, {}", e);
}
});
}
pub(super) fn handle_discovery(handlers: UdpHandlers) -> UdpHandlers { #[tokio::main(flavor = "current_thread")]
let info = get_discovery_back_info(); pub async fn lan_discover() -> ResultType<()> {
let peer = get_peer_info();
let client = DiscoveryClient::create(DiscoveryProto {
id: ipc::get_id_async().await,
peer: protobuf::MessageField::from_option(Some(peer)),
port: SERVER_UDP_PORT as i32,
..Default::default()
})
.await?;
client.lan_discover(SERVER_UDP_PORT).await
}
pub(super) async fn handle_discovery(handlers: UdpHandlers) -> UdpHandlers {
let info = get_discovery_back_info().await;
handlers handlers
.handle( .handle(
CMD_DISCOVERY.as_bytes().to_vec(), CMD_DISCOVERY.as_bytes().to_vec(),
Box::new(HandlerDiscovery::new(Some(|| true), info)), Box::new(HandlerDiscovery::new(
// Some(|| Config::get_option("enable-be-discovered") == "Y".to_owned()),
Some(|| true),
info,
)),
) )
.handle( .handle(
CMD_DISCOVERY_BACK.as_bytes().to_vec(), CMD_DISCOVERY_BACK.as_bytes().to_vec(),
@ -97,7 +111,7 @@ mod discovery {
} }
pub(super) async fn start_udp_server() -> ResultType<Server> { pub(super) async fn start_udp_server() -> ResultType<Server> {
let handlers = discovery::handle_discovery(UdpHandlers::new()); let handlers = discovery::handle_discovery(UdpHandlers::new()).await;
let mut server = Server::create(SERVER_UDP_PORT)?; let mut server = Server::create(SERVER_UDP_PORT)?;
server.start(handlers).await?; server.start(handlers).await?;

View File

@ -87,7 +87,7 @@ pub fn start(args: &mut [String]) {
let cloned = childs.clone(); let cloned = childs.clone();
std::thread::spawn(move || check_zombie(cloned)); std::thread::spawn(move || check_zombie(cloned));
let cloned = childs.clone(); let cloned = childs.clone();
tokio::spawn(async move {start_ipc(cloned)}); std::thread::spawn(move || start_ipc(cloned));
crate::common::check_software_update(); crate::common::check_software_update();
frame.event_handler(UI::new(childs)); frame.event_handler(UI::new(childs));
frame.sciter_handler(UIHostHandler {}); frame.sciter_handler(UIHostHandler {});
@ -567,6 +567,10 @@ impl UI {
fn is_xfce(&self) -> bool { fn is_xfce(&self) -> bool {
crate::platform::is_xfce() crate::platform::is_xfce()
} }
fn lan_discover(&self) {
crate::server::udp::discovery::launch_lan_discover();
}
} }
impl sciter::EventHandler for UI { impl sciter::EventHandler for UI {
@ -615,6 +619,7 @@ impl sciter::EventHandler for UI {
fn get_software_ext(); fn get_software_ext();
fn open_url(String); fn open_url(String);
fn create_shortcut(String); fn create_shortcut(String);
fn lan_discover();
} }
} }

View File

@ -51,12 +51,17 @@ class RecentSessions: Reactor.Component {
sessions = sessions.map(this.getSession); sessions = sessions.map(this.getSession);
return <div style="width: *"> return <div style="width: *">
<div .recent-sessions-title>RECENT SESSIONS</div> <div .recent-sessions-title>RECENT SESSIONS</div>
<button .button #discover>DISCOVER</button>
<div .recent-sessions-content key={sessions.length}> <div .recent-sessions-content key={sessions.length}>
{sessions} {sessions}
</div> </div>
</div>; </div>;
} }
event click $(button#discover) {
handler.lan_discover();
}
function getSession(s) { function getSession(s) {
var id = s[0]; var id = s[0];
var username = s[1]; var username = s[1];