Skip to content

Commit d4eb41e

Browse files
Merge #355
355: Ensure incoming `TcpStream` connections are closed r=Pagten a=raoulstrackx Nitro enclaves can bind to a `TcpListener` in the runner. Incoming `TcpStream` connections will be forwarded to the enclave. When the client terminates its connections, the proxy connection in the runner need to be terminated as well. Co-authored-by: Raoul Strackx <[email protected]>
2 parents 58cef55 + 21f1c34 commit d4eb41e

File tree

10 files changed

+314
-23
lines changed

10 files changed

+314
-23
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ members = [
44
"fortanix-vme/fortanix-vme-runner",
55
"fortanix-vme/tests/outgoing_connection",
66
"fortanix-vme/tests/incoming_connection",
7+
"fortanix-vme/tests/iron",
78
"intel-sgx/aesm-client",
89
"intel-sgx/dcap-provider",
910
"intel-sgx/dcap-ql-sys",

fortanix-vme/ci-common.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ function cargo_test {
100100
echo "Success"
101101
fi
102102
else
103-
${elf} -- --nocapture > ${out} 2> ${err}
103+
RUST_BACKTRACE=full ${elf} -- --nocapture > ${out} 2> ${err}
104104

105105
out=$(cat ${out} | grep -v "#" || true)
106106
expected=$(cat ./out.expected)

fortanix-vme/ci-fortanixvme.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ function run_tests {
5151
fi
5252
}
5353

54-
run_tests outgoing_connection incoming_connection
54+
run_tests\
55+
outgoing_connection \
56+
incoming_connection \
57+
iron
5558

5659
echo "********************************"
5760
echo "** All tests succeeded! **"

fortanix-vme/fortanix-vme-abi/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ impl From<SocketAddr> for Addr {
6565
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
6666
pub enum Response {
6767
Connected {
68+
/// The vsock port the proxy is listening on for an incoming connection
6869
proxy_port: u32,
6970
},
7071
Bound {

fortanix-vme/fortanix-vme-runner/src/lib.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,29 @@ impl Server {
297297

298298
if let Ok(_num) = select(None, Some(&mut read_set), None, None, None) {
299299
if read_set.contains(remote.0.as_raw_fd()) {
300-
if let Err(_) = Self::transfer_data(remote.0, remote.1, proxy.0, proxy.1) {
301-
break;
300+
match Self::transfer_data(remote.0, remote.1, proxy.0, proxy.1) {
301+
Ok(0) => {
302+
// According to the `Read` threat documentation, reading 0 bytes
303+
// indicates that the connection has been shutdown correctly. So we
304+
// close the proxy service
305+
// https://doc.rust-lang.org/std/io/trait.Read.html#tymethod.read
306+
break
307+
},
308+
Ok(_) => (),
309+
Err(e) => {
310+
eprintln!("transfer from remote failed: {:?}", e);
311+
break;
312+
}
302313
}
303314
}
304315
if read_set.contains(proxy.0.as_raw_fd()) {
305-
if let Err(_) = Self::transfer_data(proxy.0, proxy.1, remote.0, remote.1) {
306-
break;
316+
match Self::transfer_data(proxy.0, proxy.1, remote.0, remote.1) {
317+
Ok(0) => break,
318+
Ok(_) => (),
319+
Err(e) => {
320+
eprintln!("transfer from proxy failed: {:?}", e);
321+
break;
322+
}
307323
}
308324
}
309325
}

fortanix-vme/tests/iron/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "iron"
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+
iron = "0.6.1"
10+
time = "0.3.5"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
count = 0
2+
count = 1
3+
count = 2
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#![feature(once_cell)]
2+
use iron::prelude::*;
3+
use iron::{BeforeMiddleware, AfterMiddleware, typemap};
4+
use std::lazy::SyncOnceCell;
5+
use std::sync::Mutex;
6+
use time;
7+
8+
static NUM_SUCCEEDING_CONNECTIONS: SyncOnceCell<Mutex<u32>> = SyncOnceCell::new();
9+
10+
fn signal_success() {
11+
let mut count = NUM_SUCCEEDING_CONNECTIONS.get_or_init(|| Mutex::new(0)).lock().unwrap();
12+
println!("count = {}", count);
13+
*count = *count + 1;
14+
if *count == 3 {
15+
std::process::exit(0);
16+
}
17+
}
18+
19+
struct ResponseTime;
20+
21+
impl typemap::Key for ResponseTime { type Value = time::Instant; }
22+
23+
impl BeforeMiddleware for ResponseTime {
24+
fn before(&self, req: &mut Request) -> IronResult<()> {
25+
req.extensions.insert::<ResponseTime>(time::Instant::now());
26+
Ok(())
27+
}
28+
}
29+
30+
impl AfterMiddleware for ResponseTime {
31+
fn after(&self, req: &mut Request, res: Response) -> IronResult<Response> {
32+
let delta = time::Instant::now() - *req.extensions.get::<ResponseTime>().unwrap();
33+
println!("# Request took: {} ns", delta.whole_nanoseconds());
34+
signal_success();
35+
Ok(res)
36+
}
37+
}
38+
39+
fn hello_world(_: &mut Request) -> IronResult<Response> {
40+
Ok(Response::with((iron::status::Ok, "Hello World")))
41+
}
42+
43+
fn main() {
44+
let mut chain = Chain::new(hello_world);
45+
chain.link_before(ResponseTime);
46+
chain.link_after(ResponseTime);
47+
let iron = Iron::new(chain);
48+
iron.http("127.0.0.1:3000").unwrap();
49+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash -ex
2+
3+
while [ true ]
4+
do
5+
echo "Interacting with test"
6+
timeout 1s curl -k localhost:3000 || true
7+
sleep 5s
8+
done

0 commit comments

Comments
 (0)