1use rustix::net::{
2    AddressFamily, Ipv6Addr, Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV4,
3    SocketAddrV6, SocketType,
4};
5use std::net::{IpAddr, Ipv4Addr, SocketAddr};
6
7/// Test `connect_any`.
8#[test]
9fn net_v4_connect_any() -> std::io::Result<()> {
10    let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST);
11    let addr = SocketAddr::new(localhost, 0);
12    let listener =
13        rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
14    rustix::net::bind(&listener, &addr).expect("bind");
15    rustix::net::listen(&listener, 1).expect("listen");
16
17    let local_addr = rustix::net::getsockname(&listener)?;
18    let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
19    rustix::net::connect_any(&sender, &local_addr).expect("connect");
20    let request = b"Hello, World!!!";
21    let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send");
22    drop(sender);
23
24    // Not strictly required, but it makes the test simpler.
25    assert_eq!(n, request.len());
26
27    let accepted = rustix::net::accept(&listener).expect("accept");
28    let mut response = [0_u8; 128];
29    let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv");
30
31    // Not strictly required, but it makes the test simpler.
32    assert_eq!(n, request.len());
33
34    assert_eq!(request, &response[..n]);
35
36    Ok(())
37}
38
39/// Similar, but with V6.
40#[test]
41fn net_v6_connect_any() -> std::io::Result<()> {
42    let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST);
43    let addr = SocketAddr::new(localhost, 0);
44    let listener = rustix::net::socket(
45        AddressFamily::INET6,
46        SocketType::STREAM,
47        Protocol::default(),
48    )?;
49    rustix::net::bind(&listener, &addr).expect("bind");
50    rustix::net::listen(&listener, 1).expect("listen");
51
52    let local_addr = rustix::net::getsockname(&listener)?;
53    let sender = rustix::net::socket(
54        AddressFamily::INET6,
55        SocketType::STREAM,
56        Protocol::default(),
57    )?;
58    rustix::net::connect_any(&sender, &local_addr).expect("connect");
59    let request = b"Hello, World!!!";
60    let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send");
61    drop(sender);
62
63    // Not strictly required, but it makes the test simpler.
64    assert_eq!(n, request.len());
65
66    let accepted = rustix::net::accept(&listener).expect("accept");
67    let mut response = [0_u8; 128];
68    let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv");
69
70    // Not strictly required, but it makes the test simpler.
71    assert_eq!(n, request.len());
72
73    assert_eq!(request, &response[..n]);
74
75    Ok(())
76}
77
78/// Test `connect` with a `SocketAddr`.
79#[test]
80fn net_v4_connect() -> std::io::Result<()> {
81    let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST);
82    let addr = SocketAddr::new(localhost, 0);
83    let listener =
84        rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
85    rustix::net::bind(&listener, &addr).expect("bind");
86    rustix::net::listen(&listener, 1).expect("listen");
87
88    let local_addr = rustix::net::getsockname(&listener)?;
89    let local_addr = match local_addr {
90        SocketAddrAny::V4(v4) => SocketAddr::V4(v4),
91        other => panic!("unexpected socket address {:?}", other),
92    };
93    let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
94    rustix::net::connect(&sender, &local_addr).expect("connect");
95    let request = b"Hello, World!!!";
96    let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send");
97    drop(sender);
98
99    // Not strictly required, but it makes the test simpler.
100    assert_eq!(n, request.len());
101
102    let accepted = rustix::net::accept(&listener).expect("accept");
103    let mut response = [0_u8; 128];
104    let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv");
105
106    // Not strictly required, but it makes the test simpler.
107    assert_eq!(n, request.len());
108
109    assert_eq!(request, &response[..n]);
110
111    Ok(())
112}
113
114/// Similar, but use V6.
115#[test]
116fn net_v6_connect() -> std::io::Result<()> {
117    let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST);
118    let addr = SocketAddr::new(localhost, 0);
119    let listener = rustix::net::socket(
120        AddressFamily::INET6,
121        SocketType::STREAM,
122        Protocol::default(),
123    )?;
124    rustix::net::bind(&listener, &addr).expect("bind");
125    rustix::net::listen(&listener, 1).expect("listen");
126
127    let local_addr = rustix::net::getsockname(&listener)?;
128    let local_addr = match local_addr {
129        SocketAddrAny::V6(v6) => SocketAddr::V6(v6),
130        other => panic!("unexpected socket address {:?}", other),
131    };
132    let sender = rustix::net::socket(
133        AddressFamily::INET6,
134        SocketType::STREAM,
135        Protocol::default(),
136    )?;
137    rustix::net::connect(&sender, &local_addr).expect("connect");
138    let request = b"Hello, World!!!";
139    let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send");
140    drop(sender);
141
142    // Not strictly required, but it makes the test simpler.
143    assert_eq!(n, request.len());
144
145    let accepted = rustix::net::accept(&listener).expect("accept");
146    let mut response = [0_u8; 128];
147    let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv");
148
149    // Not strictly required, but it makes the test simpler.
150    assert_eq!(n, request.len());
151
152    assert_eq!(request, &response[..n]);
153
154    Ok(())
155}
156
157/// Test `bind_any`.
158#[test]
159fn net_v4_bind_any() -> std::io::Result<()> {
160    let localhost = Ipv4Addr::LOCALHOST;
161    let addr = SocketAddrV4::new(localhost, 0).into();
162    let listener =
163        rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
164    rustix::net::bind_any(&listener, &addr).expect("bind");
165    rustix::net::listen(&listener, 1).expect("listen");
166
167    let local_addr = rustix::net::getsockname(&listener)?;
168    let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
169    rustix::net::connect_any(&sender, &local_addr).expect("connect");
170    let request = b"Hello, World!!!";
171    let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send");
172    drop(sender);
173
174    // Not strictly required, but it makes the test simpler.
175    assert_eq!(n, request.len());
176
177    let accepted = rustix::net::accept(&listener).expect("accept");
178    let mut response = [0_u8; 128];
179    let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv");
180
181    // Not strictly required, but it makes the test simpler.
182    assert_eq!(n, request.len());
183
184    assert_eq!(request, &response[..n]);
185
186    Ok(())
187}
188
189/// Similar, but use V6.
190#[test]
191fn net_v6_bind_any() -> std::io::Result<()> {
192    let localhost = Ipv6Addr::LOCALHOST;
193    let addr = SocketAddrAny::V6(SocketAddrV6::new(localhost, 0, 0, 0));
194    let listener = rustix::net::socket(
195        AddressFamily::INET6,
196        SocketType::STREAM,
197        Protocol::default(),
198    )?;
199    rustix::net::bind_any(&listener, &addr).expect("bind");
200    rustix::net::listen(&listener, 1).expect("listen");
201
202    let local_addr = rustix::net::getsockname(&listener)?;
203    let sender = rustix::net::socket(
204        AddressFamily::INET6,
205        SocketType::STREAM,
206        Protocol::default(),
207    )?;
208    rustix::net::connect_any(&sender, &local_addr).expect("connect");
209    let request = b"Hello, World!!!";
210    let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send");
211    drop(sender);
212
213    // Not strictly required, but it makes the test simpler.
214    assert_eq!(n, request.len());
215
216    let accepted = rustix::net::accept(&listener).expect("accept");
217    let mut response = [0_u8; 128];
218    let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv");
219
220    // Not strictly required, but it makes the test simpler.
221    assert_eq!(n, request.len());
222
223    assert_eq!(request, &response[..n]);
224
225    Ok(())
226}
227
228/// Test `sendto`.
229#[test]
230fn net_v4_sendto() -> std::io::Result<()> {
231    let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST);
232    let addr = SocketAddr::new(localhost, 0);
233    let listener =
234        rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
235    rustix::net::bind(&listener, &addr).expect("bind");
236    rustix::net::listen(&listener, 1).expect("listen");
237
238    let local_addr = rustix::net::getsockname(&listener)?;
239    let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
240    rustix::net::connect_any(&sender, &local_addr).expect("connect");
241    let request = b"Hello, World!!!";
242    let local_addr = match local_addr {
243        SocketAddrAny::V4(v4) => SocketAddr::V4(v4),
244        other => panic!("unexpected socket address {:?}", other),
245    };
246    let n = rustix::net::sendto(&sender, request, SendFlags::empty(), &local_addr).expect("send");
247    drop(sender);
248
249    // Not strictly required, but it makes the test simpler.
250    assert_eq!(n, request.len());
251
252    let accepted = rustix::net::accept(&listener).expect("accept");
253    let mut response = [0_u8; 128];
254    let (n, from) =
255        rustix::net::recvfrom(&accepted, &mut response, RecvFlags::empty()).expect("recv");
256
257    // Not strictly required, but it makes the test simpler.
258    assert_eq!(n, request.len());
259
260    assert_eq!(request, &response[..n]);
261    assert!(from.is_none());
262
263    Ok(())
264}
265
266/// Similar, but with V6.
267#[test]
268fn net_v6_sendto() -> std::io::Result<()> {
269    let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST);
270    let addr = SocketAddr::new(localhost, 0);
271    let listener = rustix::net::socket(
272        AddressFamily::INET6,
273        SocketType::STREAM,
274        Protocol::default(),
275    )?;
276    rustix::net::bind(&listener, &addr).expect("bind");
277    rustix::net::listen(&listener, 1).expect("listen");
278
279    let local_addr = rustix::net::getsockname(&listener)?;
280    let sender = rustix::net::socket(
281        AddressFamily::INET6,
282        SocketType::STREAM,
283        Protocol::default(),
284    )?;
285    rustix::net::connect_any(&sender, &local_addr).expect("connect");
286    let request = b"Hello, World!!!";
287    let local_addr = match local_addr {
288        SocketAddrAny::V6(v6) => SocketAddr::V6(v6),
289        other => panic!("unexpected socket address {:?}", other),
290    };
291    let n = rustix::net::sendto(&sender, request, SendFlags::empty(), &local_addr).expect("send");
292    drop(sender);
293
294    // Not strictly required, but it makes the test simpler.
295    assert_eq!(n, request.len());
296
297    let accepted = rustix::net::accept(&listener).expect("accept");
298    let mut response = [0_u8; 128];
299    let (n, from) =
300        rustix::net::recvfrom(&accepted, &mut response, RecvFlags::empty()).expect("recv");
301
302    // Not strictly required, but it makes the test simpler.
303    assert_eq!(n, request.len());
304
305    assert_eq!(request, &response[..n]);
306    assert!(from.is_none());
307
308    Ok(())
309}
310
311/// Test `sendto_any`.
312#[test]
313fn net_v4_sendto_any() -> std::io::Result<()> {
314    let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST);
315    let addr = SocketAddr::new(localhost, 0);
316    let listener =
317        rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
318    rustix::net::bind(&listener, &addr).expect("bind");
319    rustix::net::listen(&listener, 1).expect("listen");
320
321    let local_addr = rustix::net::getsockname(&listener)?;
322    let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
323    rustix::net::connect_any(&sender, &local_addr).expect("connect");
324    let request = b"Hello, World!!!";
325    let n =
326        rustix::net::sendto_any(&sender, request, SendFlags::empty(), &local_addr).expect("send");
327    drop(sender);
328
329    // Not strictly required, but it makes the test simpler.
330    assert_eq!(n, request.len());
331
332    let accepted = rustix::net::accept(&listener).expect("accept");
333    let mut response = [0_u8; 128];
334    let (n, from) =
335        rustix::net::recvfrom(&accepted, &mut response, RecvFlags::empty()).expect("recv");
336
337    // Not strictly required, but it makes the test simpler.
338    assert_eq!(n, request.len());
339
340    assert_eq!(request, &response[..n]);
341    assert!(from.is_none());
342
343    Ok(())
344}
345
346/// Test `sendto_any`.
347#[test]
348fn net_v6_sendto_any() -> std::io::Result<()> {
349    let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST);
350    let addr = SocketAddr::new(localhost, 0);
351    let listener = rustix::net::socket(
352        AddressFamily::INET6,
353        SocketType::STREAM,
354        Protocol::default(),
355    )?;
356    rustix::net::bind(&listener, &addr).expect("bind");
357    rustix::net::listen(&listener, 1).expect("listen");
358
359    let local_addr = rustix::net::getsockname(&listener)?;
360    let sender = rustix::net::socket(
361        AddressFamily::INET6,
362        SocketType::STREAM,
363        Protocol::default(),
364    )?;
365    rustix::net::connect_any(&sender, &local_addr).expect("connect");
366    let request = b"Hello, World!!!";
367    let n =
368        rustix::net::sendto_any(&sender, request, SendFlags::empty(), &local_addr).expect("send");
369    drop(sender);
370
371    // Not strictly required, but it makes the test simpler.
372    assert_eq!(n, request.len());
373
374    let accepted = rustix::net::accept(&listener).expect("accept");
375    let mut response = [0_u8; 128];
376    let (n, from) =
377        rustix::net::recvfrom(&accepted, &mut response, RecvFlags::empty()).expect("recv");
378
379    // Not strictly required, but it makes the test simpler.
380    assert_eq!(n, request.len());
381
382    assert_eq!(request, &response[..n]);
383    assert!(from.is_none());
384
385    Ok(())
386}
387
388/// Test `acceptfrom`.
389#[test]
390fn net_v4_acceptfrom() -> std::io::Result<()> {
391    let localhost = IpAddr::V4(Ipv4Addr::LOCALHOST);
392    let addr = SocketAddr::new(localhost, 0);
393    let listener =
394        rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
395    rustix::net::bind(&listener, &addr).expect("bind");
396    rustix::net::listen(&listener, 1).expect("listen");
397
398    let local_addr = rustix::net::getsockname(&listener)?;
399    let sender = rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default())?;
400    rustix::net::connect_any(&sender, &local_addr).expect("connect");
401    let request = b"Hello, World!!!";
402    let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send");
403    drop(sender);
404
405    // Not strictly required, but it makes the test simpler.
406    assert_eq!(n, request.len());
407
408    let (accepted, from) = rustix::net::acceptfrom(&listener).expect("accept");
409
410    assert_ne!(from.clone().unwrap(), local_addr);
411
412    let from = match from.unwrap() {
413        SocketAddrAny::V4(v4) => v4,
414        other => panic!("unexpected socket address {:?}", other),
415    };
416    let local_addr = match local_addr {
417        SocketAddrAny::V4(v4) => v4,
418        other => panic!("unexpected socket address {:?}", other),
419    };
420
421    assert_eq!(from.clone().ip(), local_addr.ip());
422    assert_ne!(from.clone().port(), local_addr.port());
423
424    let mut response = [0_u8; 128];
425    let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv");
426
427    // Not strictly required, but it makes the test simpler.
428    assert_eq!(n, request.len());
429
430    assert_eq!(request, &response[..n]);
431
432    Ok(())
433}
434
435/// Similar, but with V6.
436#[test]
437fn net_v6_acceptfrom() -> std::io::Result<()> {
438    let localhost = IpAddr::V6(Ipv6Addr::LOCALHOST);
439    let addr = SocketAddr::new(localhost, 0);
440    let listener = rustix::net::socket(
441        AddressFamily::INET6,
442        SocketType::STREAM,
443        Protocol::default(),
444    )?;
445    rustix::net::bind(&listener, &addr).expect("bind");
446    rustix::net::listen(&listener, 1).expect("listen");
447
448    let local_addr = rustix::net::getsockname(&listener)?;
449    let sender = rustix::net::socket(
450        AddressFamily::INET6,
451        SocketType::STREAM,
452        Protocol::default(),
453    )?;
454    rustix::net::connect_any(&sender, &local_addr).expect("connect");
455    let request = b"Hello, World!!!";
456    let n = rustix::net::send(&sender, request, SendFlags::empty()).expect("send");
457    drop(sender);
458
459    // Not strictly required, but it makes the test simpler.
460    assert_eq!(n, request.len());
461
462    let (accepted, from) = rustix::net::acceptfrom(&listener).expect("accept");
463
464    assert_ne!(from.clone().unwrap(), local_addr);
465
466    let from = match from.unwrap() {
467        SocketAddrAny::V6(v6) => v6,
468        other => panic!("unexpected socket address {:?}", other),
469    };
470    let local_addr = match local_addr {
471        SocketAddrAny::V6(v6) => v6,
472        other => panic!("unexpected socket address {:?}", other),
473    };
474
475    assert_eq!(from.clone().ip(), local_addr.ip());
476    assert_ne!(from.clone().port(), local_addr.port());
477
478    let mut response = [0_u8; 128];
479    let n = rustix::net::recv(&accepted, &mut response, RecvFlags::empty()).expect("recv");
480
481    // Not strictly required, but it makes the test simpler.
482    assert_eq!(n, request.len());
483
484    assert_eq!(request, &response[..n]);
485
486    Ok(())
487}
488