@@ -9,7 +9,7 @@ use std::io::{self, Error as IoError, ErrorKind as IoErrorKind, Read, Write};
99use std:: net:: { Shutdown , TcpListener , TcpStream } ;
1010use std:: os:: unix:: io:: AsRawFd ;
1111use std:: sync:: { Arc , Mutex , RwLock } ;
12- use fortanix_vme_abi:: { self , Addr , Response , Request } ;
12+ use fortanix_vme_abi:: { self , Addr , Error as VmeError , Response , Request } ;
1313use vsock:: { self , SockAddr as VsockAddr , Std , Vsock , VsockListener , VsockStream } ;
1414
1515const PROXY_BUFF_SIZE : usize = 4192 ;
@@ -98,6 +98,10 @@ struct Connection {
9898
9999#[ derive( Clone , Debug ) ]
100100struct ConnectionInfo {
101+ /// The local address (as used by the runner)
102+ local : Addr ,
103+ /// The address of the remote party for open connection, None for server sockets
104+ peer : Addr ,
101105}
102106
103107impl Connection {
@@ -110,7 +114,10 @@ impl Connection {
110114 }
111115
112116 pub fn info ( & self ) -> ConnectionInfo {
113- ConnectionInfo { }
117+ ConnectionInfo {
118+ local : self . tcp_stream . local_addr ( ) . unwrap ( ) . into ( ) ,
119+ peer : self . tcp_stream . peer_addr ( ) . unwrap ( ) . into ( ) ,
120+ }
114121 }
115122
116123 /// Exchanges messages between the remote server and enclave. Returns on error, or when one of
@@ -317,9 +324,15 @@ impl Server {
317324 self . listeners . write ( ) . unwrap ( ) . remove ( & addr)
318325 }
319326
320- // Preliminary work for PLAT-367
321- #[ allow( dead_code) ]
322- fn connection ( & self , enclave : VsockAddr , runner : VsockAddr ) -> Option < ConnectionInfo > {
327+ fn connection_info ( & self , enclave : VsockAddr , runner_port : u32 ) -> Option < ConnectionInfo > {
328+ // There's an interesting vsock bug. When a new connection is created to the enclave in
329+ // the `handle_request_accept` function (from `ConnectionKey::from_vsock_stream`), the
330+ // local cid is different from the cid received when inspecting `enclave: VsockStream`.
331+ // Locating the cid of the runner through the `get_local_cid` does give the same result.
332+ // When PLAT-288 lands, the cid may also here be retrieved through the open runner-enclave
333+ // connection
334+ let runner_cid = vsock:: get_local_cid ( ) . unwrap_or ( vsock:: VMADDR_CID_LOCAL ) ;
335+ let runner = VsockAddr :: new ( runner_cid, runner_port) ;
323336 let k = ConnectionKey :: from_addresses ( enclave, runner) ;
324337 self . connections
325338 . read ( )
@@ -439,11 +452,53 @@ impl Server {
439452 Ok ( ( ) )
440453 }
441454
455+ fn handle_request_info ( self : Arc < Self > , enclave_port : u32 , runner_port : Option < u32 > , enclave : & mut VsockStream ) -> Result < ( ) , IoError > {
456+ let enclave_cid: u32 = enclave. peer ( ) . unwrap ( ) . parse ( ) . unwrap_or ( vsock:: VMADDR_CID_HYPERVISOR ) ;
457+ let enclave_addr = VsockAddr :: new ( enclave_cid, enclave_port) ;
458+ let response = if let Some ( runner_port) = runner_port {
459+ // We're looking for a Connection
460+ if let Some ( ConnectionInfo { local, peer } ) = self . connection_info ( enclave_addr, runner_port) {
461+ Response :: Info {
462+ local,
463+ peer : Some ( peer) ,
464+ }
465+ } else {
466+ // Connection not found
467+ Response :: Failed ( VmeError :: ConnectionNotFound )
468+ }
469+ } else {
470+ // We're looking for a Listener
471+ if let Some ( listener) = self . listener ( & enclave_addr) {
472+ let listener = listener. lock ( ) . unwrap ( ) ;
473+ Response :: Info {
474+ local : listener. listener . local_addr ( ) ?. into ( ) ,
475+ peer : None ,
476+ }
477+ } else {
478+ // Listener not found
479+ Response :: Failed ( VmeError :: ConnectionNotFound )
480+ }
481+ } ;
482+ Self :: log_communication (
483+ "runner" ,
484+ enclave. local_port ( ) . unwrap_or_default ( ) ,
485+ "enclave" ,
486+ enclave. peer_port ( ) . unwrap_or_default ( ) ,
487+ & format ! ( "{:?}" , & response) ,
488+ Direction :: Right ,
489+ "vsock" ) ;
490+ enclave. write ( & serde_cbor:: ser:: to_vec ( & response) . unwrap ( ) ) ?;
491+ Ok ( ( ) )
492+ }
493+
442494 fn handle_client ( self : Arc < Self > , stream : & mut VsockStream ) -> Result < ( ) , IoError > {
443495 match Self :: read_request ( stream) {
444496 Ok ( Request :: Connect { addr } ) => self . handle_request_connect ( & addr, stream) ?,
445497 Ok ( Request :: Bind { addr, enclave_port } ) => self . handle_request_bind ( & addr, enclave_port, stream) ?,
446498 Ok ( Request :: Accept { enclave_port } ) => self . handle_request_accept ( enclave_port, stream) ?,
499+ Ok ( Request :: Info {
500+ enclave_port,
501+ runner_port } ) => self . handle_request_info ( enclave_port, runner_port, stream) ?,
447502 Ok ( Request :: Close { enclave_port } ) => self . handle_request_close ( enclave_port, stream) ?,
448503 Err ( _e) => return Err ( IoError :: new ( IoErrorKind :: InvalidData , "Failed to read request" ) ) ,
449504 } ;
0 commit comments