2021-03-29 15:59:14 +08:00
|
|
|
use crate::client::*;
|
|
|
|
use hbb_common::{
|
|
|
|
config::PeerConfig,
|
|
|
|
log,
|
|
|
|
message_proto::*,
|
|
|
|
protobuf::Message as _,
|
|
|
|
tokio::{self, sync::mpsc},
|
|
|
|
Stream,
|
|
|
|
};
|
|
|
|
use std::sync::{Arc, RwLock};
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Session {
|
|
|
|
id: String,
|
|
|
|
lc: Arc<RwLock<LoginConfigHandler>>,
|
|
|
|
sender: mpsc::UnboundedSender<Data>,
|
|
|
|
password: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Session {
|
|
|
|
pub fn new(id: &str, sender: mpsc::UnboundedSender<Data>) -> Self {
|
|
|
|
let mut password = "".to_owned();
|
|
|
|
if PeerConfig::load(id).password.is_empty() {
|
|
|
|
password = rpassword::read_password_from_tty(Some("Enter password: ")).unwrap();
|
|
|
|
}
|
|
|
|
let session = Self {
|
|
|
|
id: id.to_owned(),
|
|
|
|
sender,
|
|
|
|
password,
|
|
|
|
lc: Default::default(),
|
|
|
|
};
|
|
|
|
session
|
|
|
|
.lc
|
|
|
|
.write()
|
|
|
|
.unwrap()
|
|
|
|
.initialize(id.to_owned(), false, true);
|
|
|
|
session
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl Interface for Session {
|
|
|
|
fn msgbox(&self, msgtype: &str, title: &str, text: &str) {
|
|
|
|
if msgtype == "input-password" {
|
|
|
|
self.sender
|
|
|
|
.send(Data::Login((self.password.clone(), true)))
|
|
|
|
.ok();
|
|
|
|
} else if msgtype == "re-input-password" {
|
|
|
|
log::error!("{}: {}", title, text);
|
|
|
|
let pass = rpassword::read_password_from_tty(Some("Enter password: ")).unwrap();
|
|
|
|
self.sender.send(Data::Login((pass, true))).ok();
|
|
|
|
} else if msgtype.contains("error") {
|
|
|
|
log::error!("{}: {}: {}", msgtype, title, text);
|
|
|
|
} else {
|
|
|
|
log::info!("{}: {}: {}", msgtype, title, text);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn handle_login_error(&mut self, err: &str) -> bool {
|
|
|
|
self.lc.write().unwrap().handle_login_error(err, self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn handle_peer_info(&mut self, pi: PeerInfo) {
|
|
|
|
let username = self.lc.read().unwrap().get_username(&pi);
|
|
|
|
self.lc.write().unwrap().handle_peer_info(username, pi);
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn handle_hash(&mut self, hash: Hash, peer: &mut Stream) {
|
|
|
|
handle_hash(self.lc.clone(), hash, self, peer).await;
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn handle_login_from_ui(&mut self, password: String, remember: bool, peer: &mut Stream) {
|
|
|
|
handle_login_from_ui(self.lc.clone(), password, remember, peer).await;
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream) {
|
|
|
|
handle_test_delay(t, peer).await;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-25 19:42:51 +08:00
|
|
|
#[tokio::main(flavor = "current_thread")]
|
2021-03-29 15:59:14 +08:00
|
|
|
pub async fn start_one_port_forward(id: String, port: i32, remote_host: String, remote_port: i32) {
|
|
|
|
crate::common::test_rendezvous_server();
|
|
|
|
crate::common::test_nat_type();
|
|
|
|
let (sender, mut receiver) = mpsc::unbounded_channel::<Data>();
|
|
|
|
let handler = Session::new(&id, sender);
|
|
|
|
handler.lc.write().unwrap().port_forward = (remote_host, remote_port);
|
|
|
|
if let Err(err) =
|
|
|
|
crate::port_forward::listen(handler.id.clone(), port, handler.clone(), receiver).await
|
|
|
|
{
|
|
|
|
log::error!("Failed to listen on {}: {}", port, err);
|
|
|
|
}
|
|
|
|
log::info!("port forward (:{}) exit", port);
|
|
|
|
}
|