@@ -9,9 +9,13 @@ use crate::{
9
9
io:: SocketAddress ,
10
10
parser:: { GetParserForOptions , OptionsParser , Parser , Token } ,
11
11
reaper:: Reaper ,
12
- EPHEMERAL_KEY_FILE , MANIFEST_FILE , PIVOT_FILE , QUORUM_FILE , SEC_APP_SOCK ,
12
+ DEFAULT_POOL_SIZE , EPHEMERAL_KEY_FILE , MANIFEST_FILE , PIVOT_FILE ,
13
+ QUORUM_FILE , SEC_APP_SOCK ,
13
14
} ;
14
15
16
+ #[ cfg( feature = "async" ) ]
17
+ use crate :: io:: AsyncStreamPool ;
18
+
15
19
/// "cid"
16
20
pub const CID : & str = "cid" ;
17
21
/// "port"
@@ -28,6 +32,8 @@ pub const EPHEMERAL_FILE_OPT: &str = "ephemeral-file";
28
32
/// Name for the option to specify the manifest file.
29
33
pub const MANIFEST_FILE_OPT : & str = "manifest-file" ;
30
34
const APP_USOCK : & str = "app-usock" ;
35
+ /// Name for the option to specify the maximum AsyncPool size.
36
+ pub const POOL_SIZE : & str = "pool-size" ;
31
37
32
38
/// CLI options for starting up the enclave server.
33
39
#[ derive( Default , Clone , Debug , PartialEq ) ]
@@ -44,11 +50,52 @@ impl EnclaveOpts {
44
50
Self { parsed }
45
51
}
46
52
53
+ /// Create a new [AsyncPool] of [AsyncStream] using the list of [SocketAddress] for the enclave server and
54
+ /// return the new [AsyncPool]. Analogous to [Self::addr] and [Self::app_addr] depending on the [app] parameter.
55
+ #[ cfg( feature = "async" ) ]
56
+ fn async_pool ( & self , app : bool ) -> AsyncStreamPool {
57
+ let pool_size: u32 = self
58
+ . parsed
59
+ . single ( POOL_SIZE )
60
+ . expect ( "invalid pool options" )
61
+ . parse ( )
62
+ . expect ( "invalid pool_size specified" ) ;
63
+ let usock_param = if app { APP_USOCK } else { USOCK } ;
64
+
65
+ match (
66
+ self . parsed . single ( CID ) ,
67
+ self . parsed . single ( PORT ) ,
68
+ self . parsed . single ( usock_param) ,
69
+ ) {
70
+ #[ cfg( feature = "vm" ) ]
71
+ ( Some ( c) , Some ( p) , None ) => {
72
+ let c = c. parse :: < u32 > ( ) . unwrap ( ) ;
73
+ let start_port = p. parse :: < u32 > ( ) . unwrap ( ) ;
74
+
75
+ let addresses = ( start_port..start_port + pool_size) . map ( |p| {
76
+ SocketAddress :: new_vsock ( c, p, crate :: io:: VMADDR_NO_FLAGS )
77
+ } ) ;
78
+
79
+ AsyncStreamPool :: new ( addresses)
80
+ }
81
+ ( None , None , Some ( u) ) => {
82
+ let addresses = ( 0 ..pool_size) . map ( |i| {
83
+ let u = format ! ( "{}_{}" , u, i) ; // add _X suffix for pooling
84
+ SocketAddress :: new_unix ( & u)
85
+ } ) ;
86
+
87
+ AsyncStreamPool :: new ( addresses)
88
+ }
89
+ _ => panic ! ( "Invalid socket opts" ) ,
90
+ }
91
+ }
92
+
47
93
/// Get the `SocketAddress` for the enclave server.
48
94
///
49
95
/// # Panics
50
96
///
51
97
/// Panics if the opts are not valid for exactly one of unix or vsock.
98
+ #[ allow( unused) ]
52
99
fn addr ( & self ) -> SocketAddress {
53
100
match (
54
101
self . parsed . single ( CID ) ,
@@ -66,6 +113,7 @@ impl EnclaveOpts {
66
113
}
67
114
}
68
115
116
+ #[ allow( unused) ]
69
117
fn app_addr ( & self ) -> SocketAddress {
70
118
SocketAddress :: new_unix (
71
119
self . parsed
@@ -135,20 +183,48 @@ impl CLI {
135
183
} else if opts. parsed . help ( ) {
136
184
println ! ( "{}" , opts. parsed. info( ) ) ;
137
185
} else {
138
- Reaper :: execute (
139
- & Handles :: new (
140
- opts. ephemeral_file ( ) ,
141
- opts. quorum_file ( ) ,
142
- opts. manifest_file ( ) ,
143
- opts. pivot_file ( ) ,
144
- ) ,
145
- opts. nsm ( ) ,
146
- opts. addr ( ) ,
147
- opts. app_addr ( ) ,
148
- None ,
149
- ) ;
186
+ Self :: run ( opts)
150
187
}
151
188
}
189
+
190
+ #[ cfg( not( feature = "async" ) ) ]
191
+ fn run ( opts : EnclaveOpts ) {
192
+ Reaper :: execute (
193
+ & Handles :: new (
194
+ opts. ephemeral_file ( ) ,
195
+ opts. quorum_file ( ) ,
196
+ opts. manifest_file ( ) ,
197
+ opts. pivot_file ( ) ,
198
+ ) ,
199
+ opts. nsm ( ) ,
200
+ opts. addr ( ) ,
201
+ opts. app_addr ( ) ,
202
+ None ,
203
+ ) ;
204
+ }
205
+
206
+ #[ cfg( feature = "async" ) ]
207
+ fn run ( opts : EnclaveOpts ) {
208
+ tokio:: runtime:: Builder :: new_current_thread ( )
209
+ . enable_all ( )
210
+ . build ( )
211
+ . expect ( "tokio main to run" )
212
+ . block_on ( async {
213
+ Reaper :: async_execute (
214
+ & Handles :: new (
215
+ opts. ephemeral_file ( ) ,
216
+ opts. quorum_file ( ) ,
217
+ opts. manifest_file ( ) ,
218
+ opts. pivot_file ( ) ,
219
+ ) ,
220
+ opts. nsm ( ) ,
221
+ opts. async_pool ( false ) ,
222
+ opts. async_pool ( true ) ,
223
+ None ,
224
+ )
225
+ . await ;
226
+ } ) ;
227
+ }
152
228
}
153
229
154
230
/// Parser for enclave CLI
@@ -201,6 +277,11 @@ impl GetParserForOptions for EnclaveParser {
201
277
. takes_value ( true )
202
278
. default_value ( SEC_APP_SOCK )
203
279
)
280
+ . token (
281
+ Token :: new ( POOL_SIZE , "the pool size for use with all socket types" )
282
+ . takes_value ( true )
283
+ . default_value ( DEFAULT_POOL_SIZE )
284
+ )
204
285
}
205
286
}
206
287
@@ -281,6 +362,20 @@ mod test {
281
362
assert_eq ! ( opts. addr( ) , SocketAddress :: new_unix( "./test.sock" ) ) ;
282
363
}
283
364
365
+ #[ test]
366
+ #[ cfg( feature = "async" ) ]
367
+ fn parse_pool_size ( ) {
368
+ let mut args: Vec < _ > =
369
+ vec ! [ "binary" , "--usock" , "./test.sock" , "--pool-size" , "7" ]
370
+ . into_iter ( )
371
+ . map ( String :: from)
372
+ . collect ( ) ;
373
+ let opts = EnclaveOpts :: new ( & mut args) ;
374
+
375
+ let pool = opts. async_pool ( false ) ;
376
+ assert_eq ! ( pool. len( ) , 7 ) ;
377
+ }
378
+
284
379
#[ test]
285
380
fn parse_manifest_file ( ) {
286
381
let mut args: Vec < _ > = vec ! [ "binary" , "--usock" , "./test.sock" ]
0 commit comments