Skip to content

Commit e6571e3

Browse files
committed
Initial enclave-runner
1 parent 6410015 commit e6571e3

File tree

10 files changed

+350
-0
lines changed

10 files changed

+350
-0
lines changed

fortanix-vme/Cargo.lock

Lines changed: 122 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fortanix-vme/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
members = [
3+
"enclave-runner",
4+
"fortanix-vme-abi",
5+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "enclave-runner"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
fortanix-vme-abi = { path = "../fortanix-vme-abi" }
10+
serde = { version = "1.0", features = ["derive"] }
11+
serde_cbor = { version = "0.10" }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod server;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use enclave_runner::server::Server;
2+
3+
fn main() {
4+
let server = Server::new();
5+
server.run().expect("Server failed");
6+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use std::thread;
2+
use std::io::{Error as IoError, ErrorKind as IoErrorKind, Write};
3+
use std::net::{Shutdown, TcpListener, TcpStream};
4+
use fortanix_vme_abi::{self, Error, Response, Request};
5+
6+
pub struct Server {
7+
port: u16,
8+
}
9+
10+
impl Server {
11+
pub fn new() -> Self {
12+
Server {
13+
port: fortanix_vme_abi::SERVER_PORT,
14+
}
15+
}
16+
17+
fn read_request(stream: &mut TcpStream) -> Result<Request, Error> {
18+
// Blocks until a full `Request` object is received
19+
let mut deser = serde_cbor::Deserializer::from_reader(stream).into_iter::<Request>();
20+
let req = deser
21+
.next()
22+
.ok_or(Error::ReadFailed)?
23+
.map_err(|e| Error::DeserializationError(e))?;
24+
Ok(req)
25+
}
26+
27+
fn handle_client(stream: &mut TcpStream) -> Result<(), IoError> {
28+
let request = Self::read_request(stream).map_err(|_e| IoError::new(IoErrorKind::InvalidInput, "Failed to read request"))?;
29+
let response = match request {
30+
Request::Connect{ addr } => {
31+
println!("Received connect request to : {:?}", addr);
32+
Response::Connected {
33+
port: 42,
34+
local_addr: "local".to_string(),
35+
peer_addr: "peer".to_string()
36+
}
37+
},
38+
};
39+
stream.write(&response.serialize().unwrap())?;
40+
Ok(())
41+
}
42+
43+
pub fn run(&self) -> std::io::Result<()> {
44+
let listener = TcpListener::bind(format!("127.0.0.1:{}", self.port))?;
45+
46+
for stream in listener.incoming() {
47+
let result = stream
48+
.map_err(|e| format!("Failed to connect to client: {}", e))
49+
.map(|mut stream| thread::Builder::new()
50+
.spawn(move || {
51+
if let Err(e) = Self::handle_client(&mut stream) {
52+
eprintln!("Error handling connection: {}, shutting connection down", e);
53+
let _ = stream.shutdown(Shutdown::Both);
54+
}
55+
}).map_err(|_| "Launch failed"));
56+
57+
if let Err(e) = result {
58+
eprintln!("Error: {}", e);
59+
}
60+
}
61+
Ok(())
62+
}
63+
}
64+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use fortanix_vme_abi::{self, Response, Request};
2+
use std::thread;
3+
use std::io::{Error as IoError, Read, Write};
4+
use std::net::TcpStream;
5+
use std::time::Duration;
6+
7+
const READ_BUFF_SIZE: usize = 10;
8+
9+
fn read_from_stream(stream: &mut TcpStream) -> Result<Vec<u8>, IoError> {
10+
let mut buff = Vec::new();
11+
buff.resize(READ_BUFF_SIZE, 0);
12+
let n = stream.read(&mut buff)?;
13+
buff.resize(n, 0);
14+
if n == READ_BUFF_SIZE {
15+
buff.append(&mut read_from_stream(stream)?);
16+
}
17+
Ok(buff)
18+
}
19+
20+
fn read_response(stream: &mut TcpStream) -> Result<Response, IoError> {
21+
let response = read_from_stream(stream)?;
22+
Ok(Response::deserialize(&response).unwrap())
23+
}
24+
25+
#[test]
26+
fn test_connect() {
27+
let _ = thread::spawn(|| {
28+
let server = enclave_runner::server::Server::new();
29+
server.run().unwrap();
30+
});
31+
thread::sleep(Duration::from_millis(1000));
32+
let mut runner = TcpStream::connect(format!("localhost:{}", fortanix_vme_abi::SERVER_PORT)).unwrap();
33+
let connect = Request::Connect {
34+
addr: "google.com".to_string(),
35+
};
36+
let buf = connect.serialize().unwrap();
37+
38+
runner.write(&buf).unwrap();
39+
let response = read_response(&mut runner).unwrap();
40+
println!("response = {:?}", response);
41+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "fortanix-vme-abi"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
10+
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
11+
compiler_builtins = { version = "0.1.0", optional = true }
12+
serde = { version = "1.0", default-features = false, features = ["derive"] }
13+
serde_cbor = { version = "0.10", default-features = false, features = ["alloc"] }
14+
15+
[features]
16+
default = ["std"]
17+
docs = []
18+
rustc-dep-of-std = ["core", "alloc", "compiler_builtins/rustc-dep-of-std"]
19+
std = []
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#![no_std]
2+
#![allow(unused)]
3+
4+
extern crate alloc;
5+
6+
#[cfg(feature="std")]
7+
extern crate std;
8+
9+
use core::fmt::{self, Display};
10+
use serde_cbor::Serializer;
11+
use serde_cbor::ser::SliceWrite;
12+
use alloc::vec::Vec;
13+
use alloc::string::String;
14+
use serde::{Deserialize, Serialize};
15+
#[cfg(feature="std")]
16+
use std::io;
17+
18+
pub const SERVER_PORT: u16 = 1024;
19+
20+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
21+
pub enum Request {
22+
Connect {
23+
addr: String,
24+
},
25+
}
26+
27+
impl Request{
28+
pub fn serialize(&self) -> Result<Vec<u8>, Error> {
29+
serde_cbor::ser::to_vec(self).map_err(|e| Error::SerializationError(e))
30+
}
31+
32+
pub fn deserialize(req: &Vec<u8>) -> Result<Self, Error> {
33+
serde_cbor::from_slice(req).map_err(|e| Error::DeserializationError(e))
34+
}
35+
}
36+
37+
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
38+
pub enum Response {
39+
Connected {
40+
port: u16,
41+
local_addr: String,
42+
peer_addr: String,
43+
},
44+
}
45+
46+
impl Response {
47+
pub fn serialize(&self) -> Result<Vec<u8>, Error> {
48+
serde_cbor::ser::to_vec(self).map_err(|e| Error::SerializationError(e))
49+
}
50+
51+
pub fn deserialize(res: &Vec<u8>) -> Result<Self, Error> {
52+
serde_cbor::from_slice(res).map_err(|e| Error::DeserializationError(e))
53+
}
54+
}
55+
56+
#[derive(Debug)]
57+
pub enum Error {
58+
DeserializationError(serde_cbor::Error),
59+
ReadFailed,
60+
SerializationError(serde_cbor::Error),
61+
}
62+
63+
impl Display for Error {
64+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65+
match self {
66+
Error::DeserializationError(_e) => write!(f, "Deserialization failed"),
67+
Error::ReadFailed => write!(f, "Read failed"),
68+
Error::SerializationError(_e) => write!(f, "Serialization failed"),
69+
}
70+
}
71+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/bin/bash -ex
2+
repo_root=$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../../../)
3+
cd ${repo_root}/fortanix-vme
4+
5+
source ci-common.sh
6+
compile
7+
8+
eif=$(mktemp /tmp/$name.eif.XXXXX)
9+
elf2eif ${elf} ${eif}
10+
eif_runner ${eif} ${out} ${err}

0 commit comments

Comments
 (0)