1b8a62b91Sopenharmony_ci#[test]
2b8a62b91Sopenharmony_cifn test_sockopts() {
3b8a62b91Sopenharmony_ci    use rustix::net::{AddressFamily, Protocol, SocketType};
4b8a62b91Sopenharmony_ci    use std::time::Duration;
5b8a62b91Sopenharmony_ci
6b8a62b91Sopenharmony_ci    let s =
7b8a62b91Sopenharmony_ci        rustix::net::socket(AddressFamily::INET, SocketType::STREAM, Protocol::default()).unwrap();
8b8a62b91Sopenharmony_ci
9b8a62b91Sopenharmony_ci    // On a new socket we shouldn't have a timeout yet.
10b8a62b91Sopenharmony_ci    assert!(
11b8a62b91Sopenharmony_ci        rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv)
12b8a62b91Sopenharmony_ci            .unwrap()
13b8a62b91Sopenharmony_ci            .is_none()
14b8a62b91Sopenharmony_ci    );
15b8a62b91Sopenharmony_ci    assert_eq!(
16b8a62b91Sopenharmony_ci        rustix::net::sockopt::get_socket_type(&s).unwrap(),
17b8a62b91Sopenharmony_ci        SocketType::STREAM
18b8a62b91Sopenharmony_ci    );
19b8a62b91Sopenharmony_ci    #[cfg(not(windows))]
20b8a62b91Sopenharmony_ci    assert!(!rustix::net::sockopt::get_socket_broadcast(&s).unwrap());
21b8a62b91Sopenharmony_ci    // On a new socket we shouldn't have a linger yet.
22b8a62b91Sopenharmony_ci    assert!(rustix::net::sockopt::get_socket_linger(&s)
23b8a62b91Sopenharmony_ci        .unwrap()
24b8a62b91Sopenharmony_ci        .is_none());
25b8a62b91Sopenharmony_ci    #[cfg(any(target_os = "android", target_os = "linux"))]
26b8a62b91Sopenharmony_ci    assert!(!rustix::net::sockopt::get_socket_passcred(&s).unwrap());
27b8a62b91Sopenharmony_ci    assert_ne!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 0);
28b8a62b91Sopenharmony_ci    assert_ne!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 77);
29b8a62b91Sopenharmony_ci    #[cfg(not(any(
30b8a62b91Sopenharmony_ci        windows,
31b8a62b91Sopenharmony_ci        target_os = "dragonfly",
32b8a62b91Sopenharmony_ci        target_os = "freebsd",
33b8a62b91Sopenharmony_ci        target_os = "ios",
34b8a62b91Sopenharmony_ci        target_os = "macos",
35b8a62b91Sopenharmony_ci        target_os = "netbsd",
36b8a62b91Sopenharmony_ci        target_os = "openbsd",
37b8a62b91Sopenharmony_ci    )))]
38b8a62b91Sopenharmony_ci    assert!(rustix::net::sockopt::get_ip_multicast_loop(&s).unwrap());
39b8a62b91Sopenharmony_ci    #[cfg(not(any(
40b8a62b91Sopenharmony_ci        windows,
41b8a62b91Sopenharmony_ci        target_os = "dragonfly",
42b8a62b91Sopenharmony_ci        target_os = "freebsd",
43b8a62b91Sopenharmony_ci        target_os = "ios",
44b8a62b91Sopenharmony_ci        target_os = "macos",
45b8a62b91Sopenharmony_ci        target_os = "netbsd",
46b8a62b91Sopenharmony_ci        target_os = "openbsd",
47b8a62b91Sopenharmony_ci    )))]
48b8a62b91Sopenharmony_ci    assert_eq!(rustix::net::sockopt::get_ip_multicast_ttl(&s).unwrap(), 1);
49b8a62b91Sopenharmony_ci    assert!(!rustix::net::sockopt::get_tcp_nodelay(&s).unwrap());
50b8a62b91Sopenharmony_ci
51b8a62b91Sopenharmony_ci    // Set a timeout.
52b8a62b91Sopenharmony_ci    rustix::net::sockopt::set_socket_timeout(
53b8a62b91Sopenharmony_ci        &s,
54b8a62b91Sopenharmony_ci        rustix::net::sockopt::Timeout::Recv,
55b8a62b91Sopenharmony_ci        Some(Duration::new(1, 1)),
56b8a62b91Sopenharmony_ci    )
57b8a62b91Sopenharmony_ci    .unwrap();
58b8a62b91Sopenharmony_ci
59b8a62b91Sopenharmony_ci    // Check that we have a timeout of at least the time we set.
60b8a62b91Sopenharmony_ci    if cfg!(not(target_os = "freebsd")) {
61b8a62b91Sopenharmony_ci        assert!(
62b8a62b91Sopenharmony_ci            rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv)
63b8a62b91Sopenharmony_ci                .unwrap()
64b8a62b91Sopenharmony_ci                .unwrap()
65b8a62b91Sopenharmony_ci                >= Duration::new(1, 1)
66b8a62b91Sopenharmony_ci        );
67b8a62b91Sopenharmony_ci    } else {
68b8a62b91Sopenharmony_ci        // On FreeBSD <= 12, it appears the system rounds the timeout down.
69b8a62b91Sopenharmony_ci        assert!(
70b8a62b91Sopenharmony_ci            rustix::net::sockopt::get_socket_timeout(&s, rustix::net::sockopt::Timeout::Recv)
71b8a62b91Sopenharmony_ci                .unwrap()
72b8a62b91Sopenharmony_ci                .unwrap()
73b8a62b91Sopenharmony_ci                >= Duration::new(1, 0)
74b8a62b91Sopenharmony_ci        );
75b8a62b91Sopenharmony_ci    }
76b8a62b91Sopenharmony_ci
77b8a62b91Sopenharmony_ci    #[cfg(not(windows))]
78b8a62b91Sopenharmony_ci    {
79b8a62b91Sopenharmony_ci        // Set the broadcast flag;
80b8a62b91Sopenharmony_ci        rustix::net::sockopt::set_socket_broadcast(&s, true).unwrap();
81b8a62b91Sopenharmony_ci
82b8a62b91Sopenharmony_ci        // Check that the broadcast flag is set. This has no effect on stream
83b8a62b91Sopenharmony_ci        // sockets, and not all platforms even remember the value.
84b8a62b91Sopenharmony_ci        #[cfg(not(any(
85b8a62b91Sopenharmony_ci            target_os = "dragonfly",
86b8a62b91Sopenharmony_ci            target_os = "freebsd",
87b8a62b91Sopenharmony_ci            target_os = "ios",
88b8a62b91Sopenharmony_ci            target_os = "macos",
89b8a62b91Sopenharmony_ci            target_os = "netbsd",
90b8a62b91Sopenharmony_ci            target_os = "openbsd",
91b8a62b91Sopenharmony_ci        )))]
92b8a62b91Sopenharmony_ci        assert!(rustix::net::sockopt::get_socket_broadcast(&s).unwrap());
93b8a62b91Sopenharmony_ci    }
94b8a62b91Sopenharmony_ci
95b8a62b91Sopenharmony_ci    // Set a linger.
96b8a62b91Sopenharmony_ci    rustix::net::sockopt::set_socket_linger(&s, Some(Duration::new(1, 1))).unwrap();
97b8a62b91Sopenharmony_ci
98b8a62b91Sopenharmony_ci    // Check that we have a linger of at least the time we set.
99b8a62b91Sopenharmony_ci    assert!(
100b8a62b91Sopenharmony_ci        dbg!(rustix::net::sockopt::get_socket_linger(&s)
101b8a62b91Sopenharmony_ci            .unwrap()
102b8a62b91Sopenharmony_ci            .unwrap())
103b8a62b91Sopenharmony_ci            >= Duration::new(1, 1)
104b8a62b91Sopenharmony_ci    );
105b8a62b91Sopenharmony_ci
106b8a62b91Sopenharmony_ci    #[cfg(any(target_os = "android", target_os = "linux"))]
107b8a62b91Sopenharmony_ci    {
108b8a62b91Sopenharmony_ci        // Set the passcred flag;
109b8a62b91Sopenharmony_ci        rustix::net::sockopt::set_socket_passcred(&s, true).unwrap();
110b8a62b91Sopenharmony_ci
111b8a62b91Sopenharmony_ci        // Check that the passcred flag is set.
112b8a62b91Sopenharmony_ci        assert!(rustix::net::sockopt::get_socket_passcred(&s).unwrap());
113b8a62b91Sopenharmony_ci    }
114b8a62b91Sopenharmony_ci
115b8a62b91Sopenharmony_ci    // Set the ip ttl.
116b8a62b91Sopenharmony_ci    rustix::net::sockopt::set_ip_ttl(&s, 77).unwrap();
117b8a62b91Sopenharmony_ci
118b8a62b91Sopenharmony_ci    // Check the ip ttl.
119b8a62b91Sopenharmony_ci    assert_eq!(rustix::net::sockopt::get_ip_ttl(&s).unwrap(), 77);
120b8a62b91Sopenharmony_ci
121b8a62b91Sopenharmony_ci    #[cfg(not(any(
122b8a62b91Sopenharmony_ci        windows,
123b8a62b91Sopenharmony_ci        target_os = "dragonfly",
124b8a62b91Sopenharmony_ci        target_os = "freebsd",
125b8a62b91Sopenharmony_ci        target_os = "ios",
126b8a62b91Sopenharmony_ci        target_os = "macos",
127b8a62b91Sopenharmony_ci        target_os = "netbsd",
128b8a62b91Sopenharmony_ci        target_os = "openbsd",
129b8a62b91Sopenharmony_ci    )))]
130b8a62b91Sopenharmony_ci    {
131b8a62b91Sopenharmony_ci        // Set the multicast loop flag;
132b8a62b91Sopenharmony_ci        rustix::net::sockopt::set_ip_multicast_loop(&s, false).unwrap();
133b8a62b91Sopenharmony_ci
134b8a62b91Sopenharmony_ci        // Check that the multicast loop flag is set.
135b8a62b91Sopenharmony_ci        assert!(!rustix::net::sockopt::get_ip_multicast_loop(&s).unwrap());
136b8a62b91Sopenharmony_ci    }
137b8a62b91Sopenharmony_ci
138b8a62b91Sopenharmony_ci    // Set the nodelay flag;
139b8a62b91Sopenharmony_ci    rustix::net::sockopt::set_tcp_nodelay(&s, true).unwrap();
140b8a62b91Sopenharmony_ci
141b8a62b91Sopenharmony_ci    // Check that the nodelay flag is set.
142b8a62b91Sopenharmony_ci    assert!(rustix::net::sockopt::get_tcp_nodelay(&s).unwrap());
143b8a62b91Sopenharmony_ci}
144