Skip to content

Commit 34d9d8f

Browse files
committed
Inbound connections
1 parent 57b724a commit 34d9d8f

File tree

2 files changed

+78
-21
lines changed
  • fortanix-vme

2 files changed

+78
-21
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,21 @@ pub enum Request {
1111
Connect {
1212
addr: String,
1313
},
14+
Bind {
15+
/// The address the listen on in the parent VM
16+
addr: String,
17+
/// The port the enclave is listening on to receive connections from the parent VM
18+
enclave_port: u32,
19+
},
1420
}
1521

1622
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
1723
pub enum Response {
1824
Connected {
1925
proxy_port: u32,
2026
},
27+
Bound {
28+
/// The TCP port the runner is listening on
29+
port: u16,
30+
},
2131
}

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

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::cmp;
55
use std::str;
66
use std::thread::{self, JoinHandle};
77
use std::io::{self, Error as IoError, ErrorKind as IoErrorKind, Read, Write};
8-
use std::net::{Shutdown, TcpStream};
8+
use std::net::{Shutdown, TcpListener, TcpStream};
99
use std::os::unix::io::AsRawFd;
1010
use fortanix_vme_abi::{self, Response, Request};
1111
use vsock::{self, Std, VsockListener, VsockStream};
@@ -19,7 +19,7 @@ enum Direction {
1919

2020
pub struct Server;
2121

22-
pub trait StreamConnection: Read + Write + AsRawFd + Sized + Send + 'static {
22+
pub trait StreamConnection: Read + Write {
2323
fn protocol() -> &'static str;
2424

2525
fn local(&self) -> io::Result<String>;
@@ -119,15 +119,15 @@ impl Server {
119119
fn transfer_data<S: StreamConnection, D: StreamConnection>(src: &mut S, src_name: &str, dst: &mut D, dst_name: &str) -> Result<usize, IoError> {
120120
let mut buff = [0; PROXY_BUFF_SIZE];
121121
let n = src.read(&mut buff[..])?;
122-
Self::log_communication(
123-
"runner",
124-
src.local_port().unwrap_or_default(),
125-
src_name,
126-
src.peer_port().unwrap_or_default(),
127-
&str::from_utf8(&buff[0..n]).unwrap_or_default(),
128-
Direction::Left,
129-
S::protocol());
130122
if n > 0 {
123+
Self::log_communication(
124+
"runner",
125+
src.local_port().unwrap_or_default(),
126+
src_name,
127+
src.peer_port().unwrap_or_default(),
128+
&str::from_utf8(&buff[0..n]).unwrap_or_default(),
129+
Direction::Left,
130+
S::protocol());
131131
dst.write_all(&buff[0..n])?;
132132
Self::log_communication(
133133
dst_name,
@@ -186,33 +186,80 @@ impl Server {
186186
let (mut proxy, _proxy_addr) = proxy_server.accept()?;
187187

188188
// Pass messages between remote server <-> enclave
189+
Self::proxy_connection((&mut remote_socket, remote_name), (&mut proxy, "proxy"));
190+
Ok(())
191+
}
192+
193+
/*
194+
* +-----------+
195+
* | remote |
196+
* +-----------+
197+
* ^
198+
* |
199+
* |
200+
* v
201+
* +----[2]-----+ +-------------+
202+
* | Runner | | enclave |
203+
* +--[3]--[1]--+ +-[ ]----[ ]--+
204+
* \ \---- enclave ------/ /
205+
* \-------- proxy --------------/
206+
*
207+
* [1] enclave
208+
* [2] remote
209+
* [3] proxy
210+
*/
211+
fn handle_request_bind(addr: &String, enclave_port: u32, enclave: &mut VsockStream) -> Result<(), IoError> {
212+
let cid: u32 = enclave.peer().unwrap().parse().unwrap_or(0);
213+
let listener = TcpListener::bind(addr)?;
214+
let port = listener.local_addr().map(|addr| addr.port())?;
215+
let response = Response::Bound{ port };
216+
Self::log_communication(
217+
"runner",
218+
enclave.local_port().unwrap_or_default(),
219+
"enclave",
220+
enclave.peer_port().unwrap_or_default(),
221+
&format!("{:?}", &response),
222+
Direction::Right,
223+
"vsock");
224+
enclave.write(&serde_cbor::ser::to_vec(&response).unwrap())?;
225+
226+
for incoming in listener.incoming() {
227+
let _ = thread::Builder::new().spawn(move || {
228+
let mut proxy = VsockStream::connect_with_cid_port(cid, enclave_port).unwrap();
229+
Self::proxy_connection((&mut incoming.unwrap(), "remote"), (&mut proxy, "proxy"));
230+
});
231+
}
232+
Ok(())
233+
}
234+
235+
fn proxy_connection(remote: (&mut TcpStream, &str), proxy: (&mut VsockStream, &str)) {
189236
loop {
190237
let mut read_set = FdSet::new();
191-
read_set.insert(proxy.as_raw_fd());
192-
read_set.insert(remote_socket.as_raw_fd());
238+
read_set.insert(remote.0.as_raw_fd());
239+
read_set.insert(proxy.0.as_raw_fd());
193240

194241
if let Ok(_num) = select(None, Some(&mut read_set), None, None, None) {
195-
if read_set.contains(proxy.as_raw_fd()) {
196-
if let Err(_) = Self::transfer_data(&mut proxy, "proxy", &mut remote_socket, remote_name) {
242+
if read_set.contains(remote.0.as_raw_fd()) {
243+
if let Err(_) = Self::transfer_data(remote.0, remote.1, proxy.0, proxy.1) {
197244
break;
198245
}
199246
}
200-
if read_set.contains(remote_socket.as_raw_fd()) {
201-
if let Err(_) = Self::transfer_data(&mut remote_socket, remote_name, &mut proxy, "proxy") {
247+
if read_set.contains(proxy.0.as_raw_fd()) {
248+
if let Err(_) = Self::transfer_data(proxy.0, proxy.1, remote.0, remote.1) {
202249
break;
203250
}
204251
}
205252
}
206253
}
207-
let _ = proxy.shutdown(Shutdown::Both);
208-
let _ = remote_socket.shutdown(Shutdown::Both);
209-
Ok(())
254+
let _ = proxy.0.shutdown(Shutdown::Both);
255+
let _ = remote.0.shutdown(Shutdown::Both);
210256
}
211257

212258
fn handle_client(stream: &mut VsockStream) -> Result<(), IoError> {
213259
match Self::read_request(stream) {
214-
Ok(Request::Connect{ addr }) => Self::handle_request_connect(&addr, stream)?,
215-
Err(_e) => return Err(IoError::new(IoErrorKind::InvalidData, "Failed to read request")),
260+
Ok(Request::Connect{ addr }) => Self::handle_request_connect(&addr, stream)?,
261+
Ok(Request::Bind{ addr, enclave_port }) => Self::handle_request_bind(&addr, enclave_port, stream)?,
262+
Err(_e) => return Err(IoError::new(IoErrorKind::InvalidData, "Failed to read request")),
216263
};
217264
Ok(())
218265
}

0 commit comments

Comments
 (0)