Skip to content

Commit

Permalink
client/rpc: Move Transport to its own module
Browse files Browse the repository at this point in the history
  • Loading branch information
kostko committed Apr 28, 2020
1 parent 5808c73 commit a6e344d
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 76 deletions.
81 changes: 5 additions & 76 deletions client/src/rpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,21 @@ use oasis_core_runtime::{
session::{Builder, Session},
types,
},
types::Body,
};

#[cfg(not(target_env = "sgx"))]
use super::api::{CallEnclaveRequest, EnclaveRPCClient};
use super::api::EnclaveRPCClient;
#[cfg(not(target_env = "sgx"))]
use super::transport::GrpcTransport;
use super::transport::{RuntimeTransport, Transport};
use crate::BoxFuture;

/// Internal send queue backlog.
const SENDQ_BACKLOG: usize = 10;

/// RPC client error.
#[derive(Debug, Fail)]
enum RpcClientError {
pub enum RpcClientError {
#[fail(display = "call failed: {}", 0)]
CallFailed(String),
#[fail(display = "expected response message, received: {:?}", 0)]
Expand All @@ -50,79 +52,6 @@ enum RpcClientError {
Dropped,
}

trait Transport: Send + Sync {
fn write_message(
&self,
ctx: Context,
session_id: types::SessionID,
data: Vec<u8>,
untrusted_plaintext: String,
) -> BoxFuture<Vec<u8>> {
// Frame message.
let frame = types::Frame {
session: session_id,
untrusted_plaintext: untrusted_plaintext,
payload: data,
};

self.write_message_impl(ctx, cbor::to_vec(&frame))
}

fn write_message_impl(&self, ctx: Context, data: Vec<u8>) -> BoxFuture<Vec<u8>>;
}

struct RuntimeTransport {
protocol: Arc<Protocol>,
endpoint: String,
}

impl Transport for RuntimeTransport {
fn write_message_impl(&self, ctx: Context, data: Vec<u8>) -> BoxFuture<Vec<u8>> {
// NOTE: This is not actually async in SGX, but futures should be
// dispatched on the current thread anyway.
let rsp = self.protocol.make_request(
ctx,
Body::HostRPCCallRequest {
endpoint: self.endpoint.clone(),
request: data,
},
);

let rsp = match rsp {
Ok(rsp) => rsp,
Err(error) => return Box::new(future::err(error)),
};

match rsp {
Body::HostRPCCallResponse { response } => Box::new(future::ok(response)),
_ => Box::new(future::err(RpcClientError::Transport.into())),
}
}
}

#[cfg(not(target_env = "sgx"))]
struct GrpcTransport {
grpc_client: EnclaveRPCClient,
runtime_id: RuntimeId,
endpoint: String,
}

#[cfg(not(target_env = "sgx"))]
impl Transport for GrpcTransport {
fn write_message_impl(&self, _ctx: Context, data: Vec<u8>) -> BoxFuture<Vec<u8>> {
let req = CallEnclaveRequest {
runtime_id: self.runtime_id,
endpoint: self.endpoint.clone(),
payload: data,
};

match self.grpc_client.call_enclave(&req, Default::default()) {
Ok(rsp) => Box::new(rsp.map(|r| r.into()).map_err(|error| error.into())),
Err(error) => Box::new(future::err(error.into())),
}
}
}

type SendqRequest = (
Arc<Context>,
types::Request,
Expand Down
1 change: 1 addition & 0 deletions client/src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
mod api;
pub mod client;
pub mod macros;
mod transport;

// Re-exports.
pub use self::client::RpcClient;
92 changes: 92 additions & 0 deletions client/src/rpc/transport.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use std::sync::Arc;

use futures::future;
#[cfg(not(target_env = "sgx"))]
use futures::Future;
use io_context::Context;

#[cfg(not(target_env = "sgx"))]
use oasis_core_runtime::common::runtime::RuntimeId;
use oasis_core_runtime::{common::cbor, protocol::Protocol, rpc::types, types::Body};

#[cfg(not(target_env = "sgx"))]
use super::api::{CallEnclaveRequest, EnclaveRPCClient};
use super::client::RpcClientError;
use crate::BoxFuture;

/// An EnclaveRPC transport.
pub trait Transport: Send + Sync {
fn write_message(
&self,
ctx: Context,
session_id: types::SessionID,
data: Vec<u8>,
untrusted_plaintext: String,
) -> BoxFuture<Vec<u8>> {
// Frame message.
let frame = types::Frame {
session: session_id,
untrusted_plaintext: untrusted_plaintext,
payload: data,
};

self.write_message_impl(ctx, cbor::to_vec(&frame))
}

fn write_message_impl(&self, ctx: Context, data: Vec<u8>) -> BoxFuture<Vec<u8>>;
}

/// A transport implementation which can be used from inside the runtime and uses the Runtime Host
/// Protocol to transport EnclaveRPC frames.
pub struct RuntimeTransport {
pub protocol: Arc<Protocol>,
pub endpoint: String,
}

impl Transport for RuntimeTransport {
fn write_message_impl(&self, ctx: Context, data: Vec<u8>) -> BoxFuture<Vec<u8>> {
// NOTE: This is not actually async in SGX, but futures should be
// dispatched on the current thread anyway.
let rsp = self.protocol.make_request(
ctx,
Body::HostRPCCallRequest {
endpoint: self.endpoint.clone(),
request: data,
},
);

let rsp = match rsp {
Ok(rsp) => rsp,
Err(error) => return Box::new(future::err(error)),
};

match rsp {
Body::HostRPCCallResponse { response } => Box::new(future::ok(response)),
_ => Box::new(future::err(RpcClientError::Transport.into())),
}
}
}

/// A transport implementation which uses gRPC to transport EnclaveRPC frames.
#[cfg(not(target_env = "sgx"))]
pub struct GrpcTransport {
pub grpc_client: EnclaveRPCClient,
pub runtime_id: RuntimeId,
pub endpoint: String,
}

#[cfg(not(target_env = "sgx"))]
impl Transport for GrpcTransport {
fn write_message_impl(&self, _ctx: Context, data: Vec<u8>) -> BoxFuture<Vec<u8>> {
let req = CallEnclaveRequest {
runtime_id: self.runtime_id,
endpoint: self.endpoint.clone(),
payload: data,
};

match self.grpc_client.call_enclave(&req, Default::default()) {
Ok(rsp) => Box::new(rsp.map(|r| r.into()).map_err(|error| error.into())),
Err(error) => Box::new(future::err(error.into())),
}
}
}

0 comments on commit a6e344d

Please sign in to comment.