1b8a62b91Sopenharmony_ci//! Test a simple IPv6 socket server and client.
2b8a62b91Sopenharmony_ci//!
3b8a62b91Sopenharmony_ci//! The client send a message and the server sends one back.
4b8a62b91Sopenharmony_ci
5b8a62b91Sopenharmony_ci#![cfg(not(any(target_os = "redox", target_os = "wasi")))]
6b8a62b91Sopenharmony_ci
7b8a62b91Sopenharmony_ciuse rustix::net::{
8b8a62b91Sopenharmony_ci    accept, bind_v6, connect_v6, getsockname, listen, recv, send, socket, AddressFamily, Ipv6Addr,
9b8a62b91Sopenharmony_ci    Protocol, RecvFlags, SendFlags, SocketAddrAny, SocketAddrV6, SocketType,
10b8a62b91Sopenharmony_ci};
11b8a62b91Sopenharmony_ciuse std::sync::{Arc, Condvar, Mutex};
12b8a62b91Sopenharmony_ciuse std::thread;
13b8a62b91Sopenharmony_ci
14b8a62b91Sopenharmony_ciconst BUFFER_SIZE: usize = 20;
15b8a62b91Sopenharmony_ci
16b8a62b91Sopenharmony_cifn server(ready: Arc<(Mutex<u16>, Condvar)>) {
17b8a62b91Sopenharmony_ci    let connection_socket = socket(
18b8a62b91Sopenharmony_ci        AddressFamily::INET6,
19b8a62b91Sopenharmony_ci        SocketType::STREAM,
20b8a62b91Sopenharmony_ci        Protocol::default(),
21b8a62b91Sopenharmony_ci    )
22b8a62b91Sopenharmony_ci    .unwrap();
23b8a62b91Sopenharmony_ci
24b8a62b91Sopenharmony_ci    let name = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 0, 0, 0);
25b8a62b91Sopenharmony_ci    bind_v6(&connection_socket, &name).unwrap();
26b8a62b91Sopenharmony_ci
27b8a62b91Sopenharmony_ci    let who = match getsockname(&connection_socket).unwrap() {
28b8a62b91Sopenharmony_ci        SocketAddrAny::V6(addr) => addr,
29b8a62b91Sopenharmony_ci        _ => panic!(),
30b8a62b91Sopenharmony_ci    };
31b8a62b91Sopenharmony_ci
32b8a62b91Sopenharmony_ci    listen(&connection_socket, 1).unwrap();
33b8a62b91Sopenharmony_ci
34b8a62b91Sopenharmony_ci    {
35b8a62b91Sopenharmony_ci        let (lock, cvar) = &*ready;
36b8a62b91Sopenharmony_ci        let mut port = lock.lock().unwrap();
37b8a62b91Sopenharmony_ci        *port = who.port();
38b8a62b91Sopenharmony_ci        cvar.notify_all();
39b8a62b91Sopenharmony_ci    }
40b8a62b91Sopenharmony_ci
41b8a62b91Sopenharmony_ci    let mut buffer = vec![0; BUFFER_SIZE];
42b8a62b91Sopenharmony_ci    let data_socket = accept(&connection_socket).unwrap();
43b8a62b91Sopenharmony_ci    let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap();
44b8a62b91Sopenharmony_ci    assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "hello, world");
45b8a62b91Sopenharmony_ci
46b8a62b91Sopenharmony_ci    send(&data_socket, b"goodnight, moon", SendFlags::empty()).unwrap();
47b8a62b91Sopenharmony_ci}
48b8a62b91Sopenharmony_ci
49b8a62b91Sopenharmony_cifn client(ready: Arc<(Mutex<u16>, Condvar)>) {
50b8a62b91Sopenharmony_ci    let port = {
51b8a62b91Sopenharmony_ci        let (lock, cvar) = &*ready;
52b8a62b91Sopenharmony_ci        let mut port = lock.lock().unwrap();
53b8a62b91Sopenharmony_ci        while *port == 0 {
54b8a62b91Sopenharmony_ci            port = cvar.wait(port).unwrap();
55b8a62b91Sopenharmony_ci        }
56b8a62b91Sopenharmony_ci        *port
57b8a62b91Sopenharmony_ci    };
58b8a62b91Sopenharmony_ci
59b8a62b91Sopenharmony_ci    let addr = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), port, 0, 0);
60b8a62b91Sopenharmony_ci    let mut buffer = vec![0; BUFFER_SIZE];
61b8a62b91Sopenharmony_ci
62b8a62b91Sopenharmony_ci    let data_socket = socket(
63b8a62b91Sopenharmony_ci        AddressFamily::INET6,
64b8a62b91Sopenharmony_ci        SocketType::STREAM,
65b8a62b91Sopenharmony_ci        Protocol::default(),
66b8a62b91Sopenharmony_ci    )
67b8a62b91Sopenharmony_ci    .unwrap();
68b8a62b91Sopenharmony_ci    connect_v6(&data_socket, &addr).unwrap();
69b8a62b91Sopenharmony_ci
70b8a62b91Sopenharmony_ci    send(&data_socket, b"hello, world", SendFlags::empty()).unwrap();
71b8a62b91Sopenharmony_ci
72b8a62b91Sopenharmony_ci    let nread = recv(&data_socket, &mut buffer, RecvFlags::empty()).unwrap();
73b8a62b91Sopenharmony_ci    assert_eq!(String::from_utf8_lossy(&buffer[..nread]), "goodnight, moon");
74b8a62b91Sopenharmony_ci}
75b8a62b91Sopenharmony_ci
76b8a62b91Sopenharmony_ci#[test]
77b8a62b91Sopenharmony_cifn test_v6() {
78b8a62b91Sopenharmony_ci    let ready = Arc::new((Mutex::new(0_u16), Condvar::new()));
79b8a62b91Sopenharmony_ci    let ready_clone = Arc::clone(&ready);
80b8a62b91Sopenharmony_ci
81b8a62b91Sopenharmony_ci    let server = thread::Builder::new()
82b8a62b91Sopenharmony_ci        .name("server".to_string())
83b8a62b91Sopenharmony_ci        .spawn(move || {
84b8a62b91Sopenharmony_ci            server(ready);
85b8a62b91Sopenharmony_ci        })
86b8a62b91Sopenharmony_ci        .unwrap();
87b8a62b91Sopenharmony_ci    let client = thread::Builder::new()
88b8a62b91Sopenharmony_ci        .name("client".to_string())
89b8a62b91Sopenharmony_ci        .spawn(move || {
90b8a62b91Sopenharmony_ci            client(ready_clone);
91b8a62b91Sopenharmony_ci        })
92b8a62b91Sopenharmony_ci        .unwrap();
93b8a62b91Sopenharmony_ci    client.join().unwrap();
94b8a62b91Sopenharmony_ci    server.join().unwrap();
95b8a62b91Sopenharmony_ci}
96