10
10
11
11
use fmt;
12
12
use io;
13
- use net:: { SocketAddr , Shutdown , Ipv4Addr , Ipv6Addr } ;
13
+ use net:: { SocketAddr , Shutdown , Ipv4Addr , Ipv6Addr , ToSocketAddrs } ;
14
14
use time:: Duration ;
15
- use sys:: { unsupported, Void } ;
15
+ use sys:: { unsupported, Void , sgx_ineffective} ;
16
+ use sys:: fd:: FileDesc ;
16
17
use convert:: TryFrom ;
18
+ use error;
19
+ use sync:: Arc ;
17
20
18
- pub struct TcpStream ( Void ) ;
21
+ use super :: abi:: usercalls;
22
+
23
+ const DEFAULT_FAKE_TTL : u32 = 64 ;
24
+
25
+ #[ derive( Debug , Clone ) ]
26
+ struct Socket {
27
+ inner : Arc < FileDesc > ,
28
+ local_addr : String ,
29
+ }
30
+
31
+ impl Socket {
32
+ fn new ( fd : usercalls:: Fd , local_addr : String ) -> Socket {
33
+ Socket { inner : Arc :: new ( FileDesc :: new ( fd) ) , local_addr }
34
+ }
35
+ }
36
+
37
+ #[ derive( Debug , Clone ) ]
38
+ pub struct TcpStream {
39
+ inner : Socket ,
40
+ peer_addr : String ,
41
+ }
42
+
43
+ fn io_err_to_addr ( result : io:: Result < & SocketAddr > ) -> io:: Result < String > {
44
+ match result {
45
+ Ok ( saddr) => Ok ( saddr. to_string ( ) ) ,
46
+ // need to downcast twice because io::Error::into_inner doesn't return the original
47
+ // value if the conversion fails
48
+ Err ( e) => if e. get_ref ( ) . and_then ( |e| e. downcast_ref :: < NonIpSockAddr > ( ) ) . is_some ( ) {
49
+ Ok ( e. into_inner ( ) . unwrap ( ) . downcast :: < NonIpSockAddr > ( ) . unwrap ( ) . host )
50
+ } else {
51
+ Err ( e)
52
+ }
53
+ }
54
+ }
55
+
56
+ fn addr_to_sockaddr ( addr : & str ) -> io:: Result < SocketAddr > {
57
+ // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry
58
+ addr. to_socket_addrs ( ) . map ( |mut it| it. next ( ) . unwrap ( ) )
59
+ }
19
60
20
61
impl TcpStream {
21
- pub fn connect ( _: io:: Result < & SocketAddr > ) -> io:: Result < TcpStream > {
22
- unsupported ( )
62
+ pub fn connect ( addr : io:: Result < & SocketAddr > ) -> io:: Result < TcpStream > {
63
+ let addr = io_err_to_addr ( addr) ?;
64
+ let ( fd, local_addr, peer_addr) = usercalls:: connect_stream ( & addr) ?;
65
+ Ok ( TcpStream { inner : Socket :: new ( fd, local_addr) , peer_addr } )
23
66
}
24
67
25
- pub fn connect_timeout ( _ : & SocketAddr , _: Duration ) -> io:: Result < TcpStream > {
26
- unsupported ( )
68
+ pub fn connect_timeout ( addr : & SocketAddr , _: Duration ) -> io:: Result < TcpStream > {
69
+ Self :: connect ( Ok ( addr ) ) // FIXME: ignoring timeout
27
70
}
28
71
29
72
pub fn set_read_timeout ( & self , _: Option < Duration > ) -> io:: Result < ( ) > {
30
- match self . 0 { }
73
+ sgx_ineffective ( ( ) )
31
74
}
32
75
33
76
pub fn set_write_timeout ( & self , _: Option < Duration > ) -> io:: Result < ( ) > {
34
- match self . 0 { }
77
+ sgx_ineffective ( ( ) )
35
78
}
36
79
37
80
pub fn read_timeout ( & self ) -> io:: Result < Option < Duration > > {
38
- match self . 0 { }
81
+ sgx_ineffective ( None )
39
82
}
40
83
41
84
pub fn write_timeout ( & self ) -> io:: Result < Option < Duration > > {
42
- match self . 0 { }
85
+ sgx_ineffective ( None )
43
86
}
44
87
45
88
pub fn peek ( & self , _: & mut [ u8 ] ) -> io:: Result < usize > {
46
- match self . 0 { }
89
+ Ok ( 0 )
47
90
}
48
91
49
- pub fn read ( & self , _ : & mut [ u8 ] ) -> io:: Result < usize > {
50
- match self . 0 { }
92
+ pub fn read ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
93
+ self . inner . inner . read ( buf )
51
94
}
52
95
53
- pub fn write ( & self , _ : & [ u8 ] ) -> io:: Result < usize > {
54
- match self . 0 { }
96
+ pub fn write ( & self , buf : & [ u8 ] ) -> io:: Result < usize > {
97
+ self . inner . inner . write ( buf )
55
98
}
56
99
57
100
pub fn peer_addr ( & self ) -> io:: Result < SocketAddr > {
58
- match self . 0 { }
101
+ addr_to_sockaddr ( & self . peer_addr )
59
102
}
60
103
61
104
pub fn socket_addr ( & self ) -> io:: Result < SocketAddr > {
62
- match self . 0 { }
105
+ addr_to_sockaddr ( & self . inner . local_addr )
63
106
}
64
107
65
108
pub fn shutdown ( & self , _: Shutdown ) -> io:: Result < ( ) > {
66
- match self . 0 { }
109
+ sgx_ineffective ( ( ) )
67
110
}
68
111
69
112
pub fn duplicate ( & self ) -> io:: Result < TcpStream > {
70
- match self . 0 { }
113
+ Ok ( self . clone ( ) )
71
114
}
72
115
73
116
pub fn set_nodelay ( & self , _: bool ) -> io:: Result < ( ) > {
74
- match self . 0 { }
117
+ sgx_ineffective ( ( ) )
75
118
}
76
119
77
120
pub fn nodelay ( & self ) -> io:: Result < bool > {
78
- match self . 0 { }
121
+ sgx_ineffective ( false )
79
122
}
80
123
81
124
pub fn set_ttl ( & self , _: u32 ) -> io:: Result < ( ) > {
82
- match self . 0 { }
125
+ sgx_ineffective ( ( ) )
83
126
}
84
127
85
128
pub fn ttl ( & self ) -> io:: Result < u32 > {
86
- match self . 0 { }
129
+ sgx_ineffective ( DEFAULT_FAKE_TTL )
87
130
}
88
131
89
132
pub fn take_error ( & self ) -> io:: Result < Option < io:: Error > > {
90
- match self . 0 { }
133
+ Ok ( None )
91
134
}
92
135
93
136
pub fn set_nonblocking ( & self , _: bool ) -> io:: Result < ( ) > {
94
- match self . 0 { }
137
+ sgx_ineffective ( ( ) )
95
138
}
96
139
}
97
140
98
- impl fmt:: Debug for TcpStream {
99
- fn fmt ( & self , _f : & mut fmt:: Formatter ) -> fmt:: Result {
100
- match self . 0 { }
101
- }
141
+ #[ derive( Debug , Clone ) ]
142
+ pub struct TcpListener {
143
+ inner : Socket ,
102
144
}
103
145
104
- pub struct TcpListener ( Void ) ;
105
-
106
146
impl TcpListener {
107
- pub fn bind ( _: io:: Result < & SocketAddr > ) -> io:: Result < TcpListener > {
108
- unsupported ( )
147
+ pub fn bind ( addr : io:: Result < & SocketAddr > ) -> io:: Result < TcpListener > {
148
+ let addr = io_err_to_addr ( addr) ?;
149
+ let ( fd, local_addr) = usercalls:: bind_stream ( & addr) ?;
150
+ Ok ( TcpListener { inner : Socket :: new ( fd, local_addr) } )
109
151
}
110
152
111
153
pub fn socket_addr ( & self ) -> io:: Result < SocketAddr > {
112
- match self . 0 { }
154
+ addr_to_sockaddr ( & self . inner . local_addr )
113
155
}
114
156
115
157
pub fn accept ( & self ) -> io:: Result < ( TcpStream , SocketAddr ) > {
116
- match self . 0 { }
158
+ let ( fd, local_addr, peer_addr) = usercalls:: accept_stream ( self . inner . inner . raw ( ) ) ?;
159
+ let ret_peer = addr_to_sockaddr ( & peer_addr) . unwrap_or_else ( |_| ( [ 0 ; 4 ] , 0 ) . into ( ) ) ;
160
+ Ok ( ( TcpStream { inner : Socket :: new ( fd, local_addr) , peer_addr } , ret_peer) )
117
161
}
118
162
119
163
pub fn duplicate ( & self ) -> io:: Result < TcpListener > {
120
- match self . 0 { }
164
+ Ok ( self . clone ( ) )
121
165
}
122
166
123
167
pub fn set_ttl ( & self , _: u32 ) -> io:: Result < ( ) > {
124
- match self . 0 { }
168
+ sgx_ineffective ( ( ) )
125
169
}
126
170
127
171
pub fn ttl ( & self ) -> io:: Result < u32 > {
128
- match self . 0 { }
172
+ sgx_ineffective ( DEFAULT_FAKE_TTL )
129
173
}
130
174
131
175
pub fn set_only_v6 ( & self , _: bool ) -> io:: Result < ( ) > {
132
- match self . 0 { }
176
+ sgx_ineffective ( ( ) )
133
177
}
134
178
135
179
pub fn only_v6 ( & self ) -> io:: Result < bool > {
136
- match self . 0 { }
180
+ sgx_ineffective ( false )
137
181
}
138
182
139
183
pub fn take_error ( & self ) -> io:: Result < Option < io:: Error > > {
140
- match self . 0 { }
184
+ Ok ( None )
141
185
}
142
186
143
187
pub fn set_nonblocking ( & self , _: bool ) -> io:: Result < ( ) > {
144
- match self . 0 { }
145
- }
146
- }
147
-
148
- impl fmt:: Debug for TcpListener {
149
- fn fmt ( & self , _f : & mut fmt:: Formatter ) -> fmt:: Result {
150
- match self . 0 { }
188
+ sgx_ineffective ( ( ) )
151
189
}
152
190
}
153
191
@@ -285,9 +323,30 @@ impl fmt::Debug for UdpSocket {
285
323
}
286
324
}
287
325
326
+ #[ derive( Debug ) ]
327
+ pub struct NonIpSockAddr {
328
+ host : String
329
+ }
330
+
331
+ impl error:: Error for NonIpSockAddr {
332
+ fn description ( & self ) -> & str {
333
+ "Failed to convert address to SocketAddr"
334
+ }
335
+ }
336
+
337
+ impl fmt:: Display for NonIpSockAddr {
338
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
339
+ write ! ( f, "Failed to convert address to SocketAddr: {}" , self . host)
340
+ }
341
+ }
342
+
288
343
pub struct LookupHost ( Void ) ;
289
344
290
345
impl LookupHost {
346
+ fn new ( host : String ) -> io:: Result < LookupHost > {
347
+ Err ( io:: Error :: new ( io:: ErrorKind :: Other , NonIpSockAddr { host } ) )
348
+ }
349
+
291
350
pub fn port ( & self ) -> u16 {
292
351
match self . 0 { }
293
352
}
@@ -303,16 +362,16 @@ impl Iterator for LookupHost {
303
362
impl < ' a > TryFrom < & ' a str > for LookupHost {
304
363
type Error = io:: Error ;
305
364
306
- fn try_from ( _v : & ' a str ) -> io:: Result < LookupHost > {
307
- unsupported ( )
365
+ fn try_from ( v : & ' a str ) -> io:: Result < LookupHost > {
366
+ LookupHost :: new ( v . to_owned ( ) )
308
367
}
309
368
}
310
369
311
370
impl < ' a > TryFrom < ( & ' a str , u16 ) > for LookupHost {
312
371
type Error = io:: Error ;
313
372
314
- fn try_from ( _v : ( & ' a str , u16 ) ) -> io:: Result < LookupHost > {
315
- unsupported ( )
373
+ fn try_from ( ( host , port ) : ( & ' a str , u16 ) ) -> io:: Result < LookupHost > {
374
+ LookupHost :: new ( format ! ( "{}:{}" , host , port ) )
316
375
}
317
376
}
318
377
0 commit comments