Implement the skeleton for the ServerManager and the spawn of the connection_ids
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
mod servercertdb;
|
||||
mod pendingdataconndb;
|
||||
mod servermanager;
|
||||
|
||||
use servercertdb::*;
|
||||
use pendingdataconndb::*;
|
||||
use servermanager::*;
|
||||
use actix::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc};
|
||||
use std::time::{Instant, Duration};
|
||||
use actix::fut::wrap_future;
|
||||
use libbonknet::*;
|
||||
use rustls::{RootCertStore, ServerConfig};
|
||||
use rustls::server::WebPkiClientVerifier;
|
||||
@@ -16,12 +19,14 @@ use actix_service::{ServiceFactoryExt as _};
|
||||
use futures::{StreamExt, SinkExt};
|
||||
use rand::random;
|
||||
use tokio_util::codec::{Framed, FramedRead, FramedWrite, LengthDelimitedCodec};
|
||||
use tracing::{info, error};
|
||||
use tracing::{info, error, warn};
|
||||
use rcgen::{Certificate, CertificateParams, DnType, KeyPair};
|
||||
use thiserror::Error;
|
||||
use tokio::io::{ReadHalf, WriteHalf};
|
||||
use tokio_util::bytes::{Bytes, BytesMut};
|
||||
use tokio::io::Error;
|
||||
use tokio::sync::{oneshot, Mutex};
|
||||
use uuid::Uuid;
|
||||
|
||||
type TransportStream = Framed<TlsStream<TcpStream>, LengthDelimitedCodec>;
|
||||
type TransportStreamTx = FramedWrite<WriteHalf<TlsStream<TcpStream>>, LengthDelimitedCodec>;
|
||||
@@ -47,131 +52,6 @@ fn generate_server_cert(root_cert: &Certificate, name: &str) -> ServerCert {
|
||||
}
|
||||
|
||||
|
||||
#[derive(MessageResponse)]
|
||||
enum SendMsgResult {
|
||||
Accepted,
|
||||
Rejected,
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "SendMsgResult")]
|
||||
struct SendMsg {
|
||||
msg: ToServerMessageBody,
|
||||
reply_channel: oneshot::Sender<FromServerReplyBody>
|
||||
}
|
||||
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "()")]
|
||||
struct SendPing;
|
||||
|
||||
struct ServerTransporter {
|
||||
rx: Option<TransportStreamRx>,
|
||||
tx: Arc<Mutex<TransportStreamTx>>,
|
||||
last_transmission: Instant,
|
||||
reply_channels: HashMap<u64, oneshot::Sender<FromServerReplyBody>>,
|
||||
}
|
||||
|
||||
impl ServerTransporter {
|
||||
fn new(transport: TransportStream) -> Self {
|
||||
let internal = transport.into_inner();
|
||||
let (srx, stx) = tokio::io::split(internal);
|
||||
let codec = LengthDelimitedCodec::new();
|
||||
let rx = FramedRead::new(srx, codec.clone());
|
||||
let tx = FramedWrite::new(stx, codec.clone());
|
||||
ServerTransporter {
|
||||
rx: Some(rx),
|
||||
tx: Arc::new(Mutex::new(tx)),
|
||||
last_transmission: Instant::now(),
|
||||
reply_channels: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Actor for ServerTransporter {
|
||||
type Context = Context<Self>;
|
||||
|
||||
fn started(&mut self, ctx: &mut Self::Context) {
|
||||
let rx = self.rx.take().expect("Rx Stream not found");
|
||||
ctx.add_stream(rx);
|
||||
ctx.run_interval(Duration::from_secs(60), |_s, c| {
|
||||
c.notify(SendPing);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<SendPing> for ServerTransporter {
|
||||
type Result = ();
|
||||
|
||||
fn handle(&mut self, _msg: SendPing, ctx: &mut Self::Context) -> Self::Result {
|
||||
let msg = ToServerMessage::Ping;
|
||||
let payload: Bytes = rmp_serde::to_vec(&msg).unwrap().into();
|
||||
let arc_tx = self.tx.clone();
|
||||
ctx.spawn(wrap_future::<_, Self>(async move {
|
||||
arc_tx.lock().await.send(payload).await
|
||||
}).map(|res, _a, _ctx| {
|
||||
info!("Ping sent result: {:?}", res);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
impl Handler<SendMsg> for ServerTransporter {
|
||||
type Result = SendMsgResult;
|
||||
|
||||
fn handle(&mut self, msg: SendMsg, ctx: &mut Self::Context) -> Self::Result {
|
||||
let mut reply_id: u64;
|
||||
if self.reply_channels.len() == u64::MAX as usize {
|
||||
return SendMsgResult::Rejected;
|
||||
}
|
||||
loop {
|
||||
reply_id = random();
|
||||
if !self.reply_channels.contains_key(&reply_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.reply_channels.insert(reply_id, msg.reply_channel);
|
||||
let msg = ToServerMessage::Msg {
|
||||
reply_id,
|
||||
body: msg.msg,
|
||||
};
|
||||
let payload: Bytes = rmp_serde::to_vec(&msg).unwrap().into();
|
||||
let arc_tx = self.tx.clone();
|
||||
ctx.spawn(async move {
|
||||
arc_tx.lock().await.send(payload).await
|
||||
}.into_actor(self).map(|res, _a, _ctx| {
|
||||
info!("ToServerMsg sent result: {:?}", res);
|
||||
}));
|
||||
SendMsgResult::Accepted
|
||||
}
|
||||
}
|
||||
|
||||
impl StreamHandler<Result<BytesMut, Error>> for ServerTransporter {
|
||||
fn handle(&mut self, item: Result<BytesMut, Error>, _ctx: &mut Self::Context) {
|
||||
match item {
|
||||
Ok(buf) => {
|
||||
use FromServerReply::*;
|
||||
let msg: FromServerReply = rmp_serde::from_slice(&buf).unwrap();
|
||||
match msg {
|
||||
Pong => {
|
||||
self.last_transmission = Instant::now();
|
||||
}
|
||||
Msg { reply_id, body } => match self.reply_channels.remove(&reply_id) {
|
||||
None => {}
|
||||
Some(reply_tx) => {
|
||||
if let Err(_e) = reply_tx.send(body) {
|
||||
error!("Oneshot channel {} got invalidated! No reply sent.", reply_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("ERROR {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() {
|
||||
// Tracing Subscriber
|
||||
@@ -211,9 +91,9 @@ async fn main() {
|
||||
server_root_prkey
|
||||
).unwrap()).unwrap());
|
||||
|
||||
let server_db_addr = ServerCertDB {
|
||||
db: HashMap::new(),
|
||||
}.start();
|
||||
let scdb_addr = ServerCertDB::new().start();
|
||||
let pdcm_addr = PendingDataConnManager::new().start();
|
||||
let sm_addr = ServerManager::new(pdcm_addr.clone()).start();
|
||||
|
||||
Server::build()
|
||||
.bind("server-command", ("localhost", 2541), move || {
|
||||
@@ -221,7 +101,8 @@ async fn main() {
|
||||
let client_root_cert_der = Arc::clone(&client_root_cert_der);
|
||||
let guestserver_root_cert_der = Arc::clone(&guestserver_root_cert_der);
|
||||
let server_root_cert = Arc::clone(&server_root_cert);
|
||||
let server_db_addr = server_db_addr.clone();
|
||||
let scdb_addr = scdb_addr.clone();
|
||||
let sm_addr = sm_addr.clone();
|
||||
|
||||
// Set up TLS service factory
|
||||
server_acceptor
|
||||
@@ -232,11 +113,14 @@ async fn main() {
|
||||
let client_root_cert_der = Arc::clone(&client_root_cert_der);
|
||||
let guestserver_root_cert_der = Arc::clone(&guestserver_root_cert_der);
|
||||
let server_root_cert = Arc::clone(&server_root_cert);
|
||||
let server_db_addr = server_db_addr.clone();
|
||||
let scdb_addr = scdb_addr.clone();
|
||||
let sm_addr = sm_addr.clone();
|
||||
async move {
|
||||
let peer_certs = stream.get_ref().1.peer_certificates().unwrap();
|
||||
let peer_cert_bytes = peer_certs.first().unwrap().to_vec();
|
||||
let peer_root_cert_der = peer_certs.last().unwrap().clone();
|
||||
let scdb_addr = scdb_addr.clone();
|
||||
let sm_addr = sm_addr.clone();
|
||||
if peer_root_cert_der == *server_root_cert_der {
|
||||
info!("Server connection");
|
||||
let mut transport = Framed::new(stream, LengthDelimitedCodec::new());
|
||||
@@ -254,15 +138,22 @@ async fn main() {
|
||||
info!("SendCommand Stream");
|
||||
let reply = ToServerConnTypeReply::OkSendCommand;
|
||||
transport.send(rmp_serde::to_vec(&reply).unwrap().into()).await.unwrap();
|
||||
server_command_handler(transport, peer_cert_bytes, &server_db_addr).await;
|
||||
server_command_handler(transport, peer_cert_bytes, scdb_addr).await;
|
||||
}
|
||||
Subscribe => {
|
||||
info!("Subscribe Stream");
|
||||
let name = match scdb_addr.send(FetchName { cert: peer_cert_bytes }).await.unwrap() {
|
||||
None => {
|
||||
error!("Cert has no name assigned!");
|
||||
let reply = ToServerConnTypeReply::GenericFailure;
|
||||
transport.send(rmp_serde::to_vec(&reply).unwrap().into()).await.unwrap();
|
||||
return Ok(());
|
||||
}
|
||||
Some(name) => name,
|
||||
};
|
||||
let reply = ToServerConnTypeReply::OkSubscribe;
|
||||
transport.send(rmp_serde::to_vec(&reply).unwrap().into()).await.unwrap();
|
||||
// TODO: If I pass transport away and the service returns, what happen to the connection?
|
||||
// in theory it will remain open but better check
|
||||
server_subscribe_handler(transport).await;
|
||||
server_subscribe_handler(transport, name, sm_addr).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,9 +168,13 @@ async fn main() {
|
||||
let server_root_cert = Arc::clone(&server_root_cert);
|
||||
let codec = LengthDelimitedCodec::new();
|
||||
let transport = Framed::new(stream, codec);
|
||||
guestserver_handler(transport, &server_db_addr, &server_root_cert).await;
|
||||
guestserver_handler(transport, scdb_addr, &server_root_cert).await;
|
||||
} else if peer_root_cert_der == *client_root_cert_der {
|
||||
info!("Client connection");
|
||||
//pdcm_addr
|
||||
let codec = LengthDelimitedCodec::new();
|
||||
let transport = Framed::new(stream, codec);
|
||||
client_handler(transport, sm_addr).await;
|
||||
} else {
|
||||
error!("Unknown Root Certificate");
|
||||
}
|
||||
@@ -293,22 +188,18 @@ async fn main() {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn server_subscribe_handler(transport: TransportStream) {
|
||||
let h = ServerTransporter::new(transport).start();
|
||||
info!("Actor spawned");
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
info!("5 seconds elapsed, sending msg");
|
||||
let (tx, rx) = oneshot::channel();
|
||||
h.send(SendMsg {
|
||||
msg: ToServerMessageBody::Required { id: "session_id".to_string() },
|
||||
reply_channel: tx,
|
||||
}).await.unwrap();
|
||||
if let Ok(item) = rx.await {
|
||||
info!("Response: {:?}", item);
|
||||
async fn server_subscribe_handler(transport: TransportStream, name: String, sm_addr: Addr<ServerManager>) {
|
||||
match sm_addr.send(StartTransporter { name, transport }).await.unwrap() {
|
||||
Ok(_) => {
|
||||
info!("Stream sent to the manager");
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error from manager: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn server_command_handler(mut transport: TransportStream, peer_cert_bytes: Vec<u8>, server_db_addr: &Addr<ServerCertDB>) {
|
||||
async fn server_command_handler(mut transport: TransportStream, peer_cert_bytes: Vec<u8>, server_db_addr: Addr<ServerCertDB>) {
|
||||
loop {
|
||||
match transport.next().await {
|
||||
None => {
|
||||
@@ -323,7 +214,25 @@ async fn server_command_handler(mut transport: TransportStream, peer_cert_bytes:
|
||||
match msg {
|
||||
ChangeName { name } => {
|
||||
info!("Changing name to {}", name);
|
||||
// TODO
|
||||
match server_db_addr.send(UnregisterServer { cert: peer_cert_bytes.clone() }).await.unwrap() {
|
||||
None => {
|
||||
info!("Nothing to unregister");
|
||||
}
|
||||
Some(old_name) => {
|
||||
warn!("Unregistered from old name {}", old_name);
|
||||
}
|
||||
}
|
||||
let reply = match server_db_addr.send(RegisterServer { cert: peer_cert_bytes.clone(), name }).await.unwrap() {
|
||||
Ok(_) => {
|
||||
info!("Registered!");
|
||||
ToServerCommandReply::NameChanged
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error registering: {:?}", e);
|
||||
ToServerCommandReply::GenericFailure
|
||||
}
|
||||
};
|
||||
transport.send(rmp_serde::to_vec(&reply).unwrap().into()).await.unwrap();
|
||||
}
|
||||
WhoAmI => {
|
||||
info!("Asked who I am");
|
||||
@@ -351,7 +260,7 @@ async fn server_command_handler(mut transport: TransportStream, peer_cert_bytes:
|
||||
}
|
||||
|
||||
// TODO: Considera creare un context dove vengono contenute tutte le chiavi e gli address da dare a tutti gli handler
|
||||
async fn guestserver_handler(mut transport: TransportStream, server_db_addr: &Addr<ServerCertDB>, server_root_cert: &Arc<Certificate>) {
|
||||
async fn guestserver_handler(mut transport: TransportStream, server_db_addr: Addr<ServerCertDB>, server_root_cert: &Arc<Certificate>) {
|
||||
loop {
|
||||
match transport.next().await {
|
||||
None => {
|
||||
@@ -396,3 +305,48 @@ async fn guestserver_handler(mut transport: TransportStream, server_db_addr: &Ad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn client_handler(mut transport: TransportStream, sm_addr: Addr<ServerManager>) {
|
||||
loop {
|
||||
match transport.next().await {
|
||||
None => {
|
||||
info!("Transport returned None");
|
||||
break;
|
||||
}
|
||||
Some(item) => {
|
||||
match item {
|
||||
Ok(buf) => {
|
||||
let msg: FromClientCommand = rmp_serde::from_slice(&buf).unwrap();
|
||||
info!("{:?}", msg);
|
||||
match msg {
|
||||
FromClientCommand::RequestServer { name } => {
|
||||
info!("REQUESTED SERVER {}", name);
|
||||
let data = sm_addr.send(RequestServer { name }).await.unwrap();
|
||||
match data {
|
||||
Ok(client_conn_id) => {
|
||||
let reply = ToClientResponse::OkRequest { conn_id: client_conn_id };
|
||||
transport.send(rmp_serde::to_vec(&reply).unwrap().into()).await.unwrap();
|
||||
info!("Sent OkRequest");
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Error! {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
FromClientCommand::ServerList => {
|
||||
info!("Requested ServerList");
|
||||
let data = sm_addr.send(GetServerList {}).await.unwrap();
|
||||
let reply = ToClientResponse::OkServerList { data };
|
||||
transport.send(rmp_serde::to_vec(&reply).unwrap().into()).await.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Disconnection: {:?}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user