@@ -204,6 +204,10 @@ const MAX_BUF_LEN: usize = ssize_t::MAX as usize;
204204#[ cfg( target_vendor = "apple" ) ]
205205const MAX_BUF_LEN : usize = c_int:: MAX as usize - 1 ;
206206
207+ // TCP_CA_NAME_MAX isn't defined in user space include files(not in libc)
208+ #[ cfg( all( feature = "all" , any( target_os = "freebsd" , target_os = "linux" ) ) ) ]
209+ const TCP_CA_NAME_MAX : usize = 16 ;
210+
207211#[ cfg( any(
208212 all(
209213 target_os = "linux" ,
@@ -2154,6 +2158,55 @@ impl crate::Socket {
21542158 )
21552159 }
21562160 }
2161+
2162+ /// Get the value of the `TCP_CONGESTION` option for this socket.
2163+ ///
2164+ /// For more information about this option, see [`set_tcp_congestion`].
2165+ ///
2166+ /// [`set_tcp_congestion`]: Socket::set_tcp_congestion
2167+ #[ cfg( all( feature = "all" , any( target_os = "freebsd" , target_os = "linux" ) ) ) ]
2168+ #[ cfg_attr(
2169+ docsrs,
2170+ doc( cfg( all( feature = "all" , any( target_os = "freebsd" , target_os = "linux" ) ) ) )
2171+ ) ]
2172+ pub fn tcp_congestion ( & self ) -> io:: Result < Vec < u8 > > {
2173+ let mut payload: [ u8 ; TCP_CA_NAME_MAX ] = [ 0 ; TCP_CA_NAME_MAX ] ;
2174+ let mut len = payload. len ( ) as libc:: socklen_t ;
2175+ syscall ! ( getsockopt(
2176+ self . as_raw( ) ,
2177+ IPPROTO_TCP ,
2178+ libc:: TCP_CONGESTION ,
2179+ payload. as_mut_ptr( ) . cast( ) ,
2180+ & mut len,
2181+ ) )
2182+ . map ( |_| {
2183+ let buf = & payload[ ..len as usize ] ;
2184+ // TODO: use `MaybeUninit::slice_assume_init_ref` once stable.
2185+ unsafe { & * ( buf as * const [ _ ] as * const [ u8 ] ) } . into ( )
2186+ } )
2187+ }
2188+
2189+ /// Set the value of the `TCP_CONGESTION` option for this socket.
2190+ ///
2191+ /// Specifies the TCP congestion control algorithm to use for this socket.
2192+ ///
2193+ /// The value must be a valid TCP congestion control algorithm name of the
2194+ /// platform. For example, Linux may supports "reno", "cubic".
2195+ #[ cfg( all( feature = "all" , any( target_os = "freebsd" , target_os = "linux" ) ) ) ]
2196+ #[ cfg_attr(
2197+ docsrs,
2198+ doc( cfg( all( feature = "all" , any( target_os = "freebsd" , target_os = "linux" ) ) ) )
2199+ ) ]
2200+ pub fn set_tcp_congestion ( & self , tcp_ca_name : & [ u8 ] ) -> io:: Result < ( ) > {
2201+ syscall ! ( setsockopt(
2202+ self . as_raw( ) ,
2203+ IPPROTO_TCP ,
2204+ libc:: TCP_CONGESTION ,
2205+ tcp_ca_name. as_ptr( ) as * const _,
2206+ tcp_ca_name. len( ) as libc:: socklen_t,
2207+ ) )
2208+ . map ( |_| ( ) )
2209+ }
21572210}
21582211
21592212#[ cfg_attr( docsrs, doc( cfg( unix) ) ) ]
0 commit comments