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