1 use test_programs::sockets::supports_ipv6;
2 use test_programs::wasi::sockets::network::{
3     ErrorCode, IpAddress, IpAddressFamily, IpSocketAddress, Network,
4 };
5 use test_programs::wasi::sockets::tcp::TcpSocket;
6 
7 const SECOND: u64 = 1_000_000_000;
8 
test_tcp_sockopt_defaults(family: IpAddressFamily)9 fn test_tcp_sockopt_defaults(family: IpAddressFamily) {
10     let sock = TcpSocket::new(family).unwrap();
11 
12     assert_eq!(sock.address_family(), family);
13 
14     sock.keep_alive_enabled().unwrap(); // Only verify that it has a default value at all, but either value is valid.
15     assert!(sock.keep_alive_idle_time().unwrap() > 0);
16     assert!(sock.keep_alive_interval().unwrap() > 0);
17     assert!(sock.keep_alive_count().unwrap() > 0);
18     assert!(sock.hop_limit().unwrap() > 0);
19     assert!(sock.receive_buffer_size().unwrap() > 0);
20     assert!(sock.send_buffer_size().unwrap() > 0);
21 }
22 
test_tcp_sockopt_input_ranges(family: IpAddressFamily)23 fn test_tcp_sockopt_input_ranges(family: IpAddressFamily) {
24     let sock = TcpSocket::new(family).unwrap();
25 
26     assert!(matches!(
27         sock.set_listen_backlog_size(0),
28         Err(ErrorCode::InvalidArgument)
29     ));
30     assert!(matches!(sock.set_listen_backlog_size(1), Ok(_))); // Unsupported sizes should be silently capped.
31     assert!(matches!(sock.set_listen_backlog_size(u64::MAX), Ok(_))); // Unsupported sizes should be silently capped.
32 
33     assert!(matches!(sock.set_keep_alive_enabled(true), Ok(_)));
34     assert!(matches!(sock.set_keep_alive_enabled(false), Ok(_)));
35 
36     assert!(matches!(
37         sock.set_keep_alive_idle_time(0),
38         Err(ErrorCode::InvalidArgument)
39     ));
40     assert!(matches!(sock.set_keep_alive_idle_time(1), Ok(_))); // Unsupported sizes should be silently clamped.
41     let idle_time = sock.keep_alive_idle_time().unwrap(); // Check that the special 0/reset behavior was not triggered by the previous line.
42     assert!(idle_time > 0 && idle_time <= 1 * SECOND);
43     assert!(matches!(sock.set_keep_alive_idle_time(u64::MAX), Ok(_))); // Unsupported sizes should be silently clamped.
44 
45     assert!(matches!(
46         sock.set_keep_alive_interval(0),
47         Err(ErrorCode::InvalidArgument)
48     ));
49     assert!(matches!(sock.set_keep_alive_interval(1), Ok(_))); // Unsupported sizes should be silently clamped.
50     let idle_time = sock.keep_alive_interval().unwrap(); // Check that the special 0/reset behavior was not triggered by the previous line.
51     assert!(idle_time > 0 && idle_time <= 1 * SECOND);
52     assert!(matches!(sock.set_keep_alive_interval(u64::MAX), Ok(_))); // Unsupported sizes should be silently clamped.
53 
54     assert!(matches!(
55         sock.set_keep_alive_count(0),
56         Err(ErrorCode::InvalidArgument)
57     ));
58     assert!(matches!(sock.set_keep_alive_count(1), Ok(_))); // Unsupported sizes should be silently clamped.
59     assert!(matches!(sock.set_keep_alive_count(u32::MAX), Ok(_))); // Unsupported sizes should be silently clamped.
60 
61     assert!(matches!(
62         sock.set_hop_limit(0),
63         Err(ErrorCode::InvalidArgument)
64     ));
65     assert!(matches!(sock.set_hop_limit(1), Ok(_)));
66     assert!(matches!(sock.set_hop_limit(u8::MAX), Ok(_)));
67 
68     assert!(matches!(
69         sock.set_receive_buffer_size(0),
70         Err(ErrorCode::InvalidArgument)
71     ));
72     assert!(matches!(sock.set_receive_buffer_size(1), Ok(_))); // Unsupported sizes should be silently capped.
73     assert!(matches!(sock.set_receive_buffer_size(u64::MAX), Ok(_))); // Unsupported sizes should be silently capped.
74     assert!(matches!(
75         sock.set_send_buffer_size(0),
76         Err(ErrorCode::InvalidArgument)
77     ));
78     assert!(matches!(sock.set_send_buffer_size(1), Ok(_))); // Unsupported sizes should be silently capped.
79     assert!(matches!(sock.set_send_buffer_size(u64::MAX), Ok(_))); // Unsupported sizes should be silently capped.
80 }
81 
test_tcp_sockopt_readback(family: IpAddressFamily)82 fn test_tcp_sockopt_readback(family: IpAddressFamily) {
83     let sock = TcpSocket::new(family).unwrap();
84 
85     sock.set_keep_alive_enabled(true).unwrap();
86     assert_eq!(sock.keep_alive_enabled().unwrap(), true);
87     sock.set_keep_alive_enabled(false).unwrap();
88     assert_eq!(sock.keep_alive_enabled().unwrap(), false);
89 
90     sock.set_keep_alive_idle_time(42 * SECOND).unwrap();
91     assert_eq!(sock.keep_alive_idle_time().unwrap(), 42 * SECOND);
92 
93     sock.set_keep_alive_interval(42 * SECOND).unwrap();
94     assert_eq!(sock.keep_alive_interval().unwrap(), 42 * SECOND);
95 
96     sock.set_keep_alive_count(42).unwrap();
97     assert_eq!(sock.keep_alive_count().unwrap(), 42);
98 
99     sock.set_hop_limit(42).unwrap();
100     assert_eq!(sock.hop_limit().unwrap(), 42);
101 
102     sock.set_receive_buffer_size(0x10000).unwrap();
103     assert_eq!(sock.receive_buffer_size().unwrap(), 0x10000);
104 
105     sock.set_send_buffer_size(0x10000).unwrap();
106     assert_eq!(sock.send_buffer_size().unwrap(), 0x10000);
107 }
108 
test_tcp_sockopt_inheritance(net: &Network, family: IpAddressFamily)109 fn test_tcp_sockopt_inheritance(net: &Network, family: IpAddressFamily) {
110     let bind_addr = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
111     let listener = TcpSocket::new(family).unwrap();
112 
113     let default_keep_alive = listener.keep_alive_enabled().unwrap();
114 
115     // Configure options on listener:
116     {
117         listener
118             .set_keep_alive_enabled(!default_keep_alive)
119             .unwrap();
120         listener.set_keep_alive_idle_time(42 * SECOND).unwrap();
121         listener.set_keep_alive_interval(42 * SECOND).unwrap();
122         listener.set_keep_alive_count(42).unwrap();
123         listener.set_hop_limit(42).unwrap();
124         listener.set_receive_buffer_size(0x10000).unwrap();
125         listener.set_send_buffer_size(0x10000).unwrap();
126     }
127 
128     listener.blocking_bind(&net, bind_addr).unwrap();
129     listener.blocking_listen().unwrap();
130     let bound_addr = listener.local_address().unwrap();
131     let client = TcpSocket::new(family).unwrap();
132     client.blocking_connect(&net, bound_addr).unwrap();
133     let (accepted_client, _, _) = listener.blocking_accept().unwrap();
134 
135     // Verify options on accepted socket:
136     {
137         assert_eq!(
138             accepted_client.keep_alive_enabled().unwrap(),
139             !default_keep_alive
140         );
141         assert_eq!(accepted_client.keep_alive_idle_time().unwrap(), 42 * SECOND);
142         assert_eq!(accepted_client.keep_alive_interval().unwrap(), 42 * SECOND);
143         assert_eq!(accepted_client.keep_alive_count().unwrap(), 42);
144         assert_eq!(accepted_client.hop_limit().unwrap(), 42);
145         assert_eq!(accepted_client.receive_buffer_size().unwrap(), 0x10000);
146         assert_eq!(accepted_client.send_buffer_size().unwrap(), 0x10000);
147     }
148 
149     // Update options on listener to something else:
150     {
151         listener.set_keep_alive_enabled(default_keep_alive).unwrap();
152         listener.set_keep_alive_idle_time(43 * SECOND).unwrap();
153         listener.set_keep_alive_interval(43 * SECOND).unwrap();
154         listener.set_keep_alive_count(43).unwrap();
155         listener.set_hop_limit(43).unwrap();
156         listener.set_receive_buffer_size(0x20000).unwrap();
157         listener.set_send_buffer_size(0x20000).unwrap();
158     }
159 
160     // Verify that the already accepted socket was not affected:
161     {
162         assert_eq!(
163             accepted_client.keep_alive_enabled().unwrap(),
164             !default_keep_alive
165         );
166         assert_eq!(accepted_client.keep_alive_idle_time().unwrap(), 42 * SECOND);
167         assert_eq!(accepted_client.keep_alive_interval().unwrap(), 42 * SECOND);
168         assert_eq!(accepted_client.keep_alive_count().unwrap(), 42);
169         assert_eq!(accepted_client.hop_limit().unwrap(), 42);
170         assert_eq!(accepted_client.receive_buffer_size().unwrap(), 0x10000);
171         assert_eq!(accepted_client.send_buffer_size().unwrap(), 0x10000);
172     }
173 }
174 
test_tcp_sockopt_after_listen(net: &Network, family: IpAddressFamily)175 fn test_tcp_sockopt_after_listen(net: &Network, family: IpAddressFamily) {
176     let bind_addr = IpSocketAddress::new(IpAddress::new_loopback(family), 0);
177     let listener = TcpSocket::new(family).unwrap();
178     listener.blocking_bind(&net, bind_addr).unwrap();
179     listener.blocking_listen().unwrap();
180     let bound_addr = listener.local_address().unwrap();
181 
182     let default_keep_alive = listener.keep_alive_enabled().unwrap();
183 
184     // Update options while the socket is already listening:
185     {
186         listener
187             .set_keep_alive_enabled(!default_keep_alive)
188             .unwrap();
189         listener.set_keep_alive_idle_time(42 * SECOND).unwrap();
190         listener.set_keep_alive_interval(42 * SECOND).unwrap();
191         listener.set_keep_alive_count(42).unwrap();
192         listener.set_hop_limit(42).unwrap();
193         listener.set_receive_buffer_size(0x10000).unwrap();
194         listener.set_send_buffer_size(0x10000).unwrap();
195     }
196 
197     let client = TcpSocket::new(family).unwrap();
198     client.blocking_connect(&net, bound_addr).unwrap();
199     let (accepted_client, _, _) = listener.blocking_accept().unwrap();
200 
201     // Verify options on accepted socket:
202     {
203         assert_eq!(
204             accepted_client.keep_alive_enabled().unwrap(),
205             !default_keep_alive
206         );
207         assert_eq!(accepted_client.keep_alive_idle_time().unwrap(), 42 * SECOND);
208         assert_eq!(accepted_client.keep_alive_interval().unwrap(), 42 * SECOND);
209         assert_eq!(accepted_client.keep_alive_count().unwrap(), 42);
210         assert_eq!(accepted_client.hop_limit().unwrap(), 42);
211         assert_eq!(accepted_client.receive_buffer_size().unwrap(), 0x10000);
212         assert_eq!(accepted_client.send_buffer_size().unwrap(), 0x10000);
213     }
214 }
215 
main()216 fn main() {
217     let net = Network::default();
218 
219     test_tcp_sockopt_defaults(IpAddressFamily::Ipv4);
220     test_tcp_sockopt_input_ranges(IpAddressFamily::Ipv4);
221     test_tcp_sockopt_readback(IpAddressFamily::Ipv4);
222     test_tcp_sockopt_inheritance(&net, IpAddressFamily::Ipv4);
223     test_tcp_sockopt_after_listen(&net, IpAddressFamily::Ipv4);
224 
225     if supports_ipv6() {
226         test_tcp_sockopt_defaults(IpAddressFamily::Ipv6);
227         test_tcp_sockopt_input_ranges(IpAddressFamily::Ipv6);
228         test_tcp_sockopt_readback(IpAddressFamily::Ipv6);
229         test_tcp_sockopt_inheritance(&net, IpAddressFamily::Ipv6);
230         test_tcp_sockopt_after_listen(&net, IpAddressFamily::Ipv6);
231     }
232 }
233