@@ -3,6 +3,9 @@ use std::io;
3
3
use std:: net:: { SocketAddr , TcpListener as StdTcpListener } ;
4
4
use std:: time:: Duration ;
5
5
6
+ #[ cfg( target_os = "wasi" ) ]
7
+ use std:: net:: { IpAddr , Ipv4Addr } ;
8
+
6
9
use tokio:: net:: TcpListener ;
7
10
use tokio:: time:: Sleep ;
8
11
use tracing:: { debug, error, trace} ;
@@ -25,6 +28,7 @@ pub struct AddrIncoming {
25
28
}
26
29
27
30
impl AddrIncoming {
31
+ #[ cfg( not( target_os = "wasi" ) ) ]
28
32
pub ( super ) fn new ( addr : & SocketAddr ) -> crate :: Result < Self > {
29
33
let std_listener = StdTcpListener :: bind ( addr) . map_err ( crate :: Error :: new_listen) ?;
30
34
@@ -41,13 +45,21 @@ impl AddrIncoming {
41
45
}
42
46
43
47
/// Creates a new `AddrIncoming` binding to provided socket address.
48
+ #[ cfg( not( target_os = "wasi" ) ) ]
44
49
pub fn bind ( addr : & SocketAddr ) -> crate :: Result < Self > {
45
50
AddrIncoming :: new ( addr)
46
51
}
47
52
48
53
/// Creates a new `AddrIncoming` from an existing `tokio::net::TcpListener`.
54
+ /// For target `wasm32-wasi`, the assumed local address is "0.0.0.0:0", since
55
+ /// WebAssembly-Wasi has no way to know the local address used for listening.
56
+ /// This could be removed, but would require refactoring a lot of code in Hyper,
57
+ /// and other downstream projects.
49
58
pub fn from_listener ( listener : TcpListener ) -> crate :: Result < Self > {
59
+ #[ cfg( not( target_os = "wasi" ) ) ]
50
60
let addr = listener. local_addr ( ) . map_err ( crate :: Error :: new_listen) ?;
61
+ #[ cfg( target_os = "wasi" ) ]
62
+ let addr = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: UNSPECIFIED ) , 0 ) ;
51
63
Ok ( AddrIncoming {
52
64
listener,
53
65
addr,
@@ -108,18 +120,26 @@ impl AddrIncoming {
108
120
loop {
109
121
match ready ! ( self . listener. poll_accept( cx) ) {
110
122
Ok ( ( socket, remote_addr) ) => {
111
- if let Some ( dur) = self . tcp_keepalive_timeout {
112
- let socket = socket2:: SockRef :: from ( & socket) ;
113
- let conf = socket2:: TcpKeepalive :: new ( ) . with_time ( dur) ;
114
- if let Err ( e) = socket. set_tcp_keepalive ( & conf) {
115
- trace ! ( "error trying to set TCP keepalive: {}" , e) ;
123
+ #[ cfg( not( target_os = "wasi" ) ) ]
124
+ {
125
+ if let Some ( dur) = self . tcp_keepalive_timeout {
126
+ let socket = socket2:: SockRef :: from ( & socket) ;
127
+ let conf = socket2:: TcpKeepalive :: new ( ) . with_time ( dur) ;
128
+ if let Err ( e) = socket. set_tcp_keepalive ( & conf) {
129
+ trace ! ( "error trying to set TCP keepalive: {}" , e) ;
130
+ }
116
131
}
132
+ if let Err ( e) = socket. set_nodelay ( self . tcp_nodelay ) {
133
+ trace ! ( "error trying to set TCP nodelay: {}" , e) ;
134
+ }
135
+ let local_addr = socket. local_addr ( ) ?;
136
+ return Poll :: Ready ( Ok ( AddrStream :: new ( socket, remote_addr, local_addr) ) ) ;
117
137
}
118
- if let Err ( e) = socket. set_nodelay ( self . tcp_nodelay ) {
119
- trace ! ( "error trying to set TCP nodelay: {}" , e) ;
138
+ #[ cfg( target_os = "wasi" ) ]
139
+ {
140
+ let local_addr = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: UNSPECIFIED ) , 0 ) ;
141
+ return Poll :: Ready ( Ok ( AddrStream :: new ( socket, remote_addr, local_addr) ) ) ;
120
142
}
121
- let local_addr = socket. local_addr ( ) ?;
122
- return Poll :: Ready ( Ok ( AddrStream :: new ( socket, remote_addr, local_addr) ) ) ;
123
143
}
124
144
Err ( e) => {
125
145
// Connection errors can be ignored directly, continue by
@@ -199,6 +219,8 @@ mod addr_stream {
199
219
use std:: net:: SocketAddr ;
200
220
#[ cfg( unix) ]
201
221
use std:: os:: unix:: io:: { AsRawFd , RawFd } ;
222
+ #[ cfg( target_os = "wasi" ) ]
223
+ use std:: os:: wasi:: io:: { AsRawFd , RawFd } ;
202
224
use tokio:: io:: { AsyncRead , AsyncWrite , ReadBuf } ;
203
225
use tokio:: net:: TcpStream ;
204
226
@@ -309,7 +331,7 @@ mod addr_stream {
309
331
}
310
332
}
311
333
312
- #[ cfg( unix) ]
334
+ #[ cfg( any ( unix, target_os = "wasi" ) ) ]
313
335
impl AsRawFd for AddrStream {
314
336
fn as_raw_fd ( & self ) -> RawFd {
315
337
self . inner . as_raw_fd ( )
0 commit comments