Skip to content

Commit

Permalink
std::net: adding acceptfilter feature for netbsd/freebsd.
Browse files Browse the repository at this point in the history
similar to linux's ext deferaccept, to filter incoming connections
before accept.
  • Loading branch information
devnexen committed Mar 20, 2024
1 parent a128516 commit 19cb05f
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
26 changes: 26 additions & 0 deletions library/std/src/os/freebsd/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#![unstable(feature = "unix_socket_ancillary_data", issue = "76915")]

use crate::ffi::CStr;
use crate::io;
use crate::os::unix::net;
use crate::sealed::Sealed;
Expand Down Expand Up @@ -40,6 +41,15 @@ pub trait UnixSocketExt: Sealed {
/// ```
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()>;

/// Get a filter name if one had been set previously on the socket.
#[unstable(feature = "acceptfilter", issue = "121891")]
fn acceptfilter(&self) -> io::Result<&CStr>;

/// Set or disable a filter on the socket to filter incoming connections
/// to defer it before accept(2)
#[unstable(feature = "acceptfilter", issue = "121891")]
fn set_acceptfilter(&self, name: &CStr) -> io::Result<()>;
}

#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
Expand All @@ -51,6 +61,14 @@ impl UnixSocketExt for net::UnixDatagram {
fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()> {
self.as_inner().set_local_creds_persistent(local_creds_persistent)
}

fn acceptfilter(&self) -> io::Result<&CStr> {
self.as_inner().acceptfilter()
}

fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
self.as_inner().set_acceptfilter(name)
}
}

#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
Expand All @@ -62,4 +80,12 @@ impl UnixSocketExt for net::UnixStream {
fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()> {
self.as_inner().set_local_creds_persistent(local_creds_persistent)
}

fn acceptfilter(&self) -> io::Result<&CStr> {
self.as_inner().acceptfilter()
}

fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
self.as_inner().set_acceptfilter(name)
}
}
26 changes: 26 additions & 0 deletions library/std/src/os/netbsd/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#![unstable(feature = "unix_socket_ancillary_data", issue = "76915")]

use crate::ffi::CStr;
use crate::io;
use crate::os::unix::net;
use crate::sealed::Sealed;
Expand Down Expand Up @@ -40,6 +41,15 @@ pub trait UnixSocketExt: Sealed {
/// ```
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
fn set_local_creds(&self, local_creds: bool) -> io::Result<()>;

/// Get a filter name if one had been set previously on the socket.
#[unstable(feature = "acceptfilter", issue = "121891")]
fn acceptfilter(&self) -> io::Result<&CStr>;

/// Set or disable a filter on the socket to filter incoming connections
/// to defer it before accept(2)
#[unstable(feature = "acceptfilter", issue = "121891")]
fn set_acceptfilter(&self, name: &CStr) -> io::Result<()>;
}

#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
Expand All @@ -51,6 +61,14 @@ impl UnixSocketExt for net::UnixDatagram {
fn set_local_creds(&self, local_creds: bool) -> io::Result<()> {
self.as_inner().set_local_creds(local_creds)
}

fn acceptfilter(&self) -> io::Result<&CStr> {
self.as_inner().acceptfilter()
}

fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
self.as_inner().set_acceptfilter(name)
}
}

#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
Expand All @@ -62,4 +80,12 @@ impl UnixSocketExt for net::UnixStream {
fn set_local_creds(&self, local_creds: bool) -> io::Result<()> {
self.as_inner().set_local_creds(local_creds)
}

fn acceptfilter(&self) -> io::Result<&CStr> {
self.as_inner().acceptfilter()
}

fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
self.as_inner().set_acceptfilter(name)
}
}
31 changes: 31 additions & 0 deletions library/std/src/sys/pal/unix/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,37 @@ impl Socket {
Ok(raw as u32)
}

#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
pub fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
if !name.to_bytes().is_empty() {
const AF_NAME_MAX: usize = 16;
let mut buf = [0; AF_NAME_MAX];
for (src, dst) in name.to_bytes().iter().zip(&mut buf[..AF_NAME_MAX - 1]) {
*dst = *src as i8;
}
let mut arg: libc::accept_filter_arg = unsafe { mem::zeroed() };
arg.af_name = buf;
setsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER, &mut arg)
} else {
setsockopt(
self,
libc::SOL_SOCKET,
libc::SO_ACCEPTFILTER,
core::ptr::null_mut() as *mut c_void,
)
}
}

#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
pub fn acceptfilter(&self) -> io::Result<&CStr> {
let arg: libc::accept_filter_arg =
getsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER)?;
let s: &[u8] =
unsafe { core::slice::from_raw_parts(arg.af_name.as_ptr() as *const u8, 16) };
let name = CStr::from_bytes_with_nul(s).unwrap();
Ok(name)
}

#[cfg(any(target_os = "android", target_os = "linux",))]
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int)
Expand Down

0 comments on commit 19cb05f

Please sign in to comment.