From 39a16eab7dc19f16bb81bc7a53b78b05a727b3ba Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 15 Nov 2024 16:10:20 -0700 Subject: [PATCH] Add the TCP_FUNCTION_BLK socket option, on FreeBSD --- changelog/2539.added.md | 1 + src/sys/socket/sockopt.rs | 11 +++++++++++ test/sys/test_sockopt.rs | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 changelog/2539.added.md diff --git a/changelog/2539.added.md b/changelog/2539.added.md new file mode 100644 index 0000000000..c42b7dbd65 --- /dev/null +++ b/changelog/2539.added.md @@ -0,0 +1 @@ +Add the `TCP_FUNCTION_BLK` sockopt, on FreeBSD. diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 408f8acb65..10704bbdcf 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -300,7 +300,18 @@ sockopt_impl!( libc::SO_REUSEPORT_LB, bool ); +#[cfg(target_os = "freebsd")] #[cfg(feature = "net")] +sockopt_impl!( + #[cfg_attr(docsrs, doc(cfg(feature = "net")))] + /// Select or query the set of functions that TCP will use for this connection. This allows a + /// user to select an alternate TCP stack. + TcpFunctionBlk, + Both, + libc::IPPROTO_TCP, + libc::TCP_FUNCTION_BLK, + libc::tcp_function_set +); sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] /// Used to disable Nagle's algorithm. diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 3cecbf7d7f..b6e78c1839 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -281,6 +281,28 @@ fn test_tcp_congestion() { assert_eq!(getsockopt(&fd, sockopt::TcpCongestion).unwrap(), val); } +#[test] +#[cfg(target_os = "freebsd")] +fn test_tcp_function_blk() { + use std::ffi::CStr; + + let fd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + + let tfs = getsockopt(&fd, sockopt::TcpFunctionBlk).unwrap(); + let name = unsafe{ CStr::from_ptr(tfs.function_set_name.as_ptr()) }; + assert!(!name.to_bytes().is_empty()); + + // We can't know at compile time what options are available. So just test the setter by a + // no-op set. + setsockopt(&fd, sockopt::TcpFunctionBlk, &tfs).unwrap(); +} + #[test] #[cfg(linux_android)] fn test_bindtodevice() {