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