From 930c9a9803df565a6733f4c6b5b1b198282c7b33 Mon Sep 17 00:00:00 2001 From: Ammar Zuberi Date: Tue, 17 Nov 2020 00:10:44 -0800 Subject: [PATCH] Additional Linux socket options Added support for setting/getting value of: * TCP Maximum Segment Size (TCP_MAXSEG) * Socket Mark (SO_MARK) Signed-off-by: Ammar Zuberi --- src/socket.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ src/sys/unix.rs | 24 ++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/src/socket.rs b/src/socket.rs index 95eb31d6..b8b48cfd 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -369,6 +369,49 @@ impl Socket { self.inner.set_ttl(ttl) } + /// Gets the value of the `TCP_MAXSEG` option on this socket. + /// + /// The `TCP_MAXSEG` option denotes the TCP Maximum Segment + /// Size and is only available on TCP sockets. + #[cfg(unix)] + pub fn mss(&self) -> io::Result { + self.inner.mss() + } + + /// Sets the value of the `TCP_MAXSEG` option on this socket. + /// + /// The `TCP_MAXSEG` option denotes the TCP Maximum Segment + /// Size and is only available on TCP sockets. + #[cfg(unix)] + pub fn set_mss(&self, mss: u32) -> io::Result<()> { + self.inner.set_mss(mss) + } + + /// Gets the value for the `SO_MARK` option on this socket. + /// + /// This value gets the socket mark field for each packet sent through + /// this socket. + /// + /// This function is only available on Linux and requires the + /// `CAP_NET_ADMIN` capability. + #[cfg(target_os = "linux")] + pub fn mark(&self) -> io::Result { + self.inner.mark() + } + + /// Sets the value for the `SO_MARK` option on this socket. + /// + /// This value sets the socket mark field for each packet sent through + /// this socket. Changing the mark can be used for mark-based routing + /// without netfilter or for packet filtering. + /// + /// This function is only available on Linux and requires the + /// `CAP_NET_ADMIN` capability. + #[cfg(target_os = "linux")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + self.inner.set_mark(mark) + } + /// Gets the value of the `IPV6_UNICAST_HOPS` option for this socket. /// /// Specifies the hop limit for ipv6 unicast packets diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 5e55fa81..784187c5 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -534,6 +534,30 @@ impl Socket { unsafe { self.setsockopt(libc::IPPROTO_IP, libc::IP_TTL, ttl as c_int) } } + pub fn mss(&self) -> io::Result { + unsafe { + let raw: c_int = self.getsockopt(libc::IPPROTO_TCP, libc::TCP_MAXSEG)?; + Ok(raw as u32) + } + } + + pub fn set_mss(&self, mss: u32) -> io::Result<()> { + unsafe { self.setsockopt(libc::IPPROTO_TCP, libc::TCP_MAXSEG, mss as c_int) } + } + + #[cfg(target_os = "linux")] + pub fn mark(&self) -> io::Result { + unsafe { + let raw: c_int = self.getsockopt(libc::SOL_SOCKET, libc::SO_MARK)?; + Ok(raw as u32) + } + } + + #[cfg(target_os = "linux")] + pub fn set_mark(&self, mark: u32) -> io::Result<()> { + unsafe { self.setsockopt(libc::SOL_SOCKET, libc::SO_MARK, mark as c_int) } + } + pub fn unicast_hops_v6(&self) -> io::Result { unsafe { let raw: c_int = self.getsockopt(libc::IPPROTO_IPV6, libc::IPV6_UNICAST_HOPS)?;