From 220942b80ac4289fc1ae0daa39ed116da33648d2 Mon Sep 17 00:00:00 2001 From: Gregor Reitzenstein Date: Tue, 17 Nov 2020 14:28:04 +0100 Subject: [PATCH] Session / Connection / Bootstrap split --- src/api/machine.rs | 22 ++++++++++++++++++---- src/api/machines.rs | 18 ++++++++++++++++-- src/connection.rs | 31 ++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/api/machine.rs b/src/api/machine.rs index a616f85..88f467b 100644 --- a/src/api/machine.rs +++ b/src/api/machine.rs @@ -6,7 +6,15 @@ use capnp::Error; struct Machine; -impl read::Server for Machine { +impl Machine { + pub fn new() -> Self { + Machine + } +} + +struct Read; + +impl read::Server for Read { fn info(&mut self, _params: read::InfoParams, _results: read::InfoResults) @@ -16,7 +24,9 @@ impl read::Server for Machine { } } -impl write::Server for Machine { +struct Write; + +impl write::Server for Write { fn use_(&mut self, _params: write::UseParams, _results: write::UseResults) @@ -26,7 +36,9 @@ impl write::Server for Machine { } } -impl manage::Server for Machine { +struct Manage; + +impl manage::Server for Manage { fn ok(&mut self, _params: manage::OkParams, _results: manage::OkResults) @@ -36,7 +48,9 @@ impl manage::Server for Machine { } } -impl admin::Server for Machine { +struct Admin; + +impl admin::Server for Admin { fn force_set_state(&mut self, _params: admin::ForceSetStateParams, _results: admin::ForceSetStateResults) diff --git a/src/api/machines.rs b/src/api/machines.rs index 378941f..7ef8b9e 100644 --- a/src/api/machines.rs +++ b/src/api/machines.rs @@ -1,9 +1,23 @@ -use crate::schema::api_capnp::machines; +use std::sync::Arc; use capnp::capability::Promise; use capnp::Error; -struct Machines; +use crate::schema::api_capnp::machines; +use crate::connection::Session; + +/// An implementation of the `Machines` API +struct Machines { + /// A reference to the connection — as long as at least one API endpoint is + /// still alive the session has to be as well. + session: Arc, +} + +impl Machines { + pub fn new(session: Arc) -> Self { + Self { session } + } +} impl machines::Server for Machines { fn list_machines(&mut self, diff --git a/src/connection.rs b/src/connection.rs index d130e59..37163ec 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use slog::Logger; use smol::net::TcpStream; @@ -14,22 +16,32 @@ use capnp_rpc::{twoparty, rpc_twoparty_capnp}; use capnp::capability::{Params, Results, Promise, FromServer}; /// Connection context -struct Connection { +// TODO this should track over several connections +pub struct Session { log: Logger, user: Option, } -impl Connection { +impl Session { pub fn new(log: Logger) -> Self { let user = None; - Self { log, user } + Session { log, user } } } +struct Bootstrap { + session: Arc +} + +impl Bootstrap { + pub fn new(session: Arc) -> Self { + Self { session } + } +} use connection_capnp::bootstrap::*; -impl connection_capnp::bootstrap::Server for Connection { +impl connection_capnp::bootstrap::Server for Bootstrap { fn auth(&mut self, _: Params, mut res: Results @@ -37,7 +49,7 @@ impl connection_capnp::bootstrap::Server for Connection { // Forbid mutltiple authentication for now // TODO: When should we allow multiple auth and how do me make sure that does not leak // priviledges (e.g. due to previously issues caps)? - if self.user.is_none() { + if self.session.user.is_none() { res.get().set_auth(capnp_rpc::new_client(auth::Auth::new())) } @@ -48,7 +60,7 @@ impl connection_capnp::bootstrap::Server for Connection { _: Params, mut res: Results ) -> Promise<(), capnp::Error> { - if self.user.is_some() { + if self.session.user.is_some() { } Promise::ok(()) @@ -92,14 +104,15 @@ async fn handshake(log: &Logger, stream: &mut TcpStream) -> Result<()> { pub async fn handle_connection(log: Logger, mut stream: TcpStream) -> Result<()> { //handshake(&log, &mut stream).await?; - let mut conn = Connection::new(log); - let rpc: connection_capnp::bootstrap::Client = capnp_rpc::new_client(conn); + let session = Arc::new(Session::new(log)); + let boots = Bootstrap::new(session); + let rpc: connection_capnp::bootstrap::Client = capnp_rpc::new_client(boots); let network = twoparty::VatNetwork::new(stream.clone(), stream, rpc_twoparty_capnp::Side::Server, Default::default()); let rpc_system = capnp_rpc::RpcSystem::new(Box::new(network), Some(rpc.client)); - rpc_system.await; + rpc_system.await.unwrap(); Ok(()) }