Skip to content

Commit 85c2f2d

Browse files
committed
TCP_FASTOPEN option for Socket
- Supported platforms: Linux-like, FreeBSD, macOS, Windows - ref rust-lang#49
1 parent acde0da commit 85c2f2d

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

src/socket.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,81 @@ impl Socket {
14571457
.map(|recv_tos| recv_tos > 0)
14581458
}
14591459
}
1460+
1461+
/// Set `TCP_FASTOPEN` option for this socket.
1462+
///
1463+
/// ## Windows
1464+
///
1465+
/// Windows supports TCP Fast Open since Windows 10.
1466+
///
1467+
/// <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options>
1468+
///
1469+
/// `value` is a boolean with only `0` and `1`.
1470+
///
1471+
/// ## Linux
1472+
///
1473+
/// Linux supports TCP Fast Open since 3.7.
1474+
///
1475+
/// <https://lwn.net/Articles/508865/>
1476+
///
1477+
/// The option `value`, `qlen`, specifies this server's limit on the size of the queue of TFO requests that have
1478+
/// not yet completed the three-way handshake (see the remarks on prevention of resource-exhaustion attacks above).
1479+
///
1480+
/// It was recommended to be `5` in this document.
1481+
///
1482+
/// ## macOS
1483+
///
1484+
/// `value` is a boolean with only `0` and `1`.
1485+
///
1486+
/// ## FreeBSD
1487+
///
1488+
/// FreeBSD supports TCP Fast Open since 12.0.
1489+
///
1490+
/// Example program: <https://people.freebsd.org/~pkelsey/tfo-tools/tfo-srv.c>
1491+
///
1492+
/// `value` is a boolean with only `0` and `1`.
1493+
#[cfg(any(
1494+
target_os = "linux",
1495+
target_os = "android",
1496+
target_os = "freebsd",
1497+
target_os = "macos",
1498+
target_os = "ios",
1499+
target_os = "watchos",
1500+
target_os = "tvos",
1501+
target_os = "windows"
1502+
))]
1503+
pub fn set_tcp_fastopen(&self, value: u32) -> io::Result<()> {
1504+
unsafe {
1505+
setsockopt::<c_int>(
1506+
self.as_raw(),
1507+
sys::IPPROTO_TCP,
1508+
sys::TCP_FASTOPEN,
1509+
value as c_int,
1510+
)
1511+
}
1512+
}
1513+
1514+
/// Get the value of `TCP_FASTOPEN` option for this socket.
1515+
///
1516+
/// For more information about this option, see [`set_tcp_fastopen`].
1517+
///
1518+
/// [`set_tcp_fastopen`]: Socket::set_tcp_fastopen
1519+
#[cfg(any(
1520+
target_os = "linux",
1521+
target_os = "android",
1522+
target_os = "freebsd",
1523+
target_os = "macos",
1524+
target_os = "ios",
1525+
target_os = "watchos",
1526+
target_os = "tvos",
1527+
target_os = "windows"
1528+
))]
1529+
pub fn tcp_fastopen(&self) -> io::Result<u32> {
1530+
unsafe {
1531+
getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_TCP, sys::TCP_FASTOPEN)
1532+
.map(|c| c as u32)
1533+
}
1534+
}
14601535
}
14611536

14621537
/// Socket options for IPv6 sockets, get/set using `IPPROTO_IPV6`.

src/sys/unix.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,17 @@ use libc::TCP_KEEPALIVE as KEEPALIVE_TIME;
157157
#[cfg(not(any(target_vendor = "apple", target_os = "haiku", target_os = "openbsd")))]
158158
use libc::TCP_KEEPIDLE as KEEPALIVE_TIME;
159159

160+
#[cfg(any(
161+
target_os = "linux",
162+
target_os = "android",
163+
target_os = "freebsd",
164+
target_os = "macos",
165+
target_os = "ios",
166+
target_os = "watchos",
167+
target_os = "tvos"
168+
))]
169+
pub(crate) use libc::TCP_FASTOPEN;
170+
160171
/// Helper macro to execute a system call that returns an `io::Result`.
161172
macro_rules! syscall {
162173
($fn: ident ( $($arg: expr),* $(,)* ) ) => {{

src/sys/windows.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ pub(crate) use windows_sys::Win32::Networking::WinSock::{
7878
};
7979
pub(crate) const IPPROTO_IP: c_int = windows_sys::Win32::Networking::WinSock::IPPROTO_IP as c_int;
8080
pub(crate) const SOL_SOCKET: c_int = windows_sys::Win32::Networking::WinSock::SOL_SOCKET as c_int;
81+
pub(crate) const TCP_FASTOPEN: c_int =
82+
windows_sys::Win32::Networking::WinSock::TCP_FASTOPEN as c_int;
8183

8284
/// Type used in set/getsockopt to retrieve the `TCP_NODELAY` option.
8385
///

0 commit comments

Comments
 (0)