diff options
Diffstat (limited to 'src/sys/unix/tcp.rs')
-rw-r--r-- | src/sys/unix/tcp.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs index 81b371b..65b7400 100644 --- a/src/sys/unix/tcp.rs +++ b/src/sys/unix/tcp.rs @@ -1,4 +1,5 @@ use std::io; +use std::mem; use std::mem::{size_of, MaybeUninit}; use std::net::{self, SocketAddr}; use std::time::Duration; @@ -58,6 +59,63 @@ pub(crate) fn set_reuseaddr(socket: TcpSocket, reuseaddr: bool) -> io::Result<() )).map(|_| ()) } +pub(crate) fn get_reuseaddr(socket: TcpSocket) -> io::Result<bool> { + let mut optval: libc::c_int = 0; + let mut optlen = mem::size_of::<libc::c_int>() as libc::socklen_t; + + syscall!(getsockopt( + socket, + libc::SOL_SOCKET, + libc::SO_REUSEADDR, + &mut optval as *mut _ as *mut _, + &mut optlen, + ))?; + + Ok(optval != 0) +} + +#[cfg(all(unix, not(any(target_os = "solaris", target_os = "illumos"))))] +pub(crate) fn set_reuseport(socket: TcpSocket, reuseport: bool) -> io::Result<()> { + let val: libc::c_int = if reuseport { 1 } else { 0 }; + + syscall!(setsockopt( + socket, + libc::SOL_SOCKET, + libc::SO_REUSEPORT, + &val as *const libc::c_int as *const libc::c_void, + size_of::<libc::c_int>() as libc::socklen_t, + )).map(|_| ()) +} + +#[cfg(all(unix, not(any(target_os = "solaris", target_os = "illumos"))))] +pub(crate) fn get_reuseport(socket: TcpSocket) -> io::Result<bool> { + let mut optval: libc::c_int = 0; + let mut optlen = mem::size_of::<libc::c_int>() as libc::socklen_t; + + syscall!(getsockopt( + socket, + libc::SOL_SOCKET, + libc::SO_REUSEPORT, + &mut optval as *mut _ as *mut _, + &mut optlen, + ))?; + + Ok(optval != 0) +} + +pub(crate) fn get_localaddr(socket: TcpSocket) -> io::Result<SocketAddr> { + let mut addr: libc::sockaddr_storage = unsafe { std::mem::zeroed() }; + let mut length = size_of::<libc::sockaddr_storage>() as libc::socklen_t; + + syscall!(getsockname( + socket, + &mut addr as *mut _ as *mut _, + &mut length + ))?; + + unsafe { to_socket_addr(&addr) } +} + pub(crate) fn set_linger(socket: TcpSocket, dur: Option<Duration>) -> io::Result<()> { let val: libc::linger = libc::linger { l_onoff: if dur.is_some() { 1 } else { 0 }, |