mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-12-20 07:07:50 +08:00
136 lines
4.5 KiB
Rust
136 lines
4.5 KiB
Rust
use crate::{allow_err, anyhow::anyhow, ResultType};
|
|
use protobuf::Message;
|
|
use std::{net::SocketAddr, sync::Arc};
|
|
use tokio::{self, stream::StreamExt, sync::mpsc};
|
|
|
|
const QUIC_HBB: &[&[u8]] = &[b"hbb"];
|
|
const SERVER_NAME: &str = "hbb";
|
|
|
|
type Sender = mpsc::UnboundedSender<Value>;
|
|
type Receiver = mpsc::UnboundedReceiver<Value>;
|
|
|
|
pub fn new_server(socket: std::net::UdpSocket) -> ResultType<(Server, SocketAddr)> {
|
|
let mut transport_config = quinn::TransportConfig::default();
|
|
transport_config.stream_window_uni(0);
|
|
let mut server_config = quinn::ServerConfig::default();
|
|
server_config.transport = Arc::new(transport_config);
|
|
let mut server_config = quinn::ServerConfigBuilder::new(server_config);
|
|
server_config.protocols(QUIC_HBB);
|
|
// server_config.enable_keylog();
|
|
// server_config.use_stateless_retry(true);
|
|
let mut endpoint = quinn::Endpoint::builder();
|
|
endpoint.listen(server_config.build());
|
|
let (end, incoming) = endpoint.with_socket(socket)?;
|
|
Ok((Server { incoming }, end.local_addr()?))
|
|
}
|
|
|
|
pub async fn new_client(local_addr: &SocketAddr, peer: &SocketAddr) -> ResultType<Connection> {
|
|
let mut endpoint = quinn::Endpoint::builder();
|
|
let mut client_config = quinn::ClientConfigBuilder::default();
|
|
client_config.protocols(QUIC_HBB);
|
|
//client_config.enable_keylog();
|
|
endpoint.default_client_config(client_config.build());
|
|
let (endpoint, _) = endpoint.bind(local_addr)?;
|
|
let new_conn = endpoint.connect(peer, SERVER_NAME)?.await?;
|
|
Connection::new_for_client(new_conn.connection).await
|
|
}
|
|
|
|
pub struct Server {
|
|
incoming: quinn::Incoming,
|
|
}
|
|
|
|
impl Server {
|
|
#[inline]
|
|
pub async fn next(&mut self) -> ResultType<Option<Connection>> {
|
|
Connection::new_for_server(&mut self.incoming).await
|
|
}
|
|
}
|
|
|
|
pub struct Connection {
|
|
conn: quinn::Connection,
|
|
tx: quinn::SendStream,
|
|
rx: Receiver,
|
|
}
|
|
|
|
type Value = ResultType<Vec<u8>>;
|
|
|
|
impl Connection {
|
|
async fn new_for_server(incoming: &mut quinn::Incoming) -> ResultType<Option<Self>> {
|
|
if let Some(conn) = incoming.next().await {
|
|
let quinn::NewConnection {
|
|
connection: conn,
|
|
// uni_streams,
|
|
mut bi_streams,
|
|
..
|
|
} = conn.await?;
|
|
let (tx, rx) = mpsc::unbounded_channel::<Value>();
|
|
tokio::spawn(async move {
|
|
loop {
|
|
let stream = bi_streams.next().await;
|
|
if let Some(stream) = stream {
|
|
let stream = match stream {
|
|
Err(e) => {
|
|
tx.send(Err(e.into())).ok();
|
|
break;
|
|
}
|
|
Ok(s) => s,
|
|
};
|
|
let cloned = tx.clone();
|
|
tokio::spawn(async move {
|
|
allow_err!(handle_request(stream.1, cloned).await);
|
|
});
|
|
} else {
|
|
tx.send(Err(anyhow!("Reset by the peer"))).ok();
|
|
break;
|
|
}
|
|
}
|
|
log::info!("Exit connection outer loop");
|
|
});
|
|
let tx = conn.open_uni().await?;
|
|
Ok(Some(Self { conn, tx, rx }))
|
|
} else {
|
|
Ok(None)
|
|
}
|
|
}
|
|
|
|
async fn new_for_client(conn: quinn::Connection) -> ResultType<Self> {
|
|
let (tx, rx_quic) = conn.open_bi().await?;
|
|
let (tx_mpsc, rx) = mpsc::unbounded_channel::<Value>();
|
|
tokio::spawn(async move {
|
|
allow_err!(handle_request(rx_quic, tx_mpsc).await);
|
|
});
|
|
Ok(Self { conn, tx, rx })
|
|
}
|
|
|
|
#[inline]
|
|
pub async fn next(&mut self) -> Option<Value> {
|
|
// None is returned when all Sender halves have dropped,
|
|
// indicating that no further values can be sent on the channel.
|
|
self.rx.recv().await
|
|
}
|
|
|
|
#[inline]
|
|
pub fn remote_address(&self) -> SocketAddr {
|
|
self.conn.remote_address()
|
|
}
|
|
|
|
#[inline]
|
|
pub async fn send_raw(&mut self, bytes: &[u8]) -> ResultType<()> {
|
|
self.tx.write_all(bytes).await?;
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
pub async fn send(&mut self, msg: &dyn Message) -> ResultType<()> {
|
|
match msg.write_to_bytes() {
|
|
Ok(bytes) => self.send_raw(&bytes).await?,
|
|
err => allow_err!(err),
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
async fn handle_request(rx: quinn::RecvStream, tx: Sender) -> ResultType<()> {
|
|
Ok(())
|
|
}
|