about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Carlier <devnexen@gmail.com>2024-03-02 01:51:58 +0000
committerDavid Carlier <devnexen@gmail.com>2024-03-20 18:15:31 +0000
commit19cb05fd7807e2ea0d7b4f8613eb8b0ad646ce61 (patch)
tree367abaf3601685af45a5d931a8693cbdee4be050
parenta128516cf9de352ae1f9d430ed730363c7ca3c0c (diff)
downloadrust-19cb05fd7807e2ea0d7b4f8613eb8b0ad646ce61.tar.gz
rust-19cb05fd7807e2ea0d7b4f8613eb8b0ad646ce61.zip
std::net: adding acceptfilter feature for netbsd/freebsd.
similar to linux's ext deferaccept, to filter incoming connections
before accept.
-rw-r--r--library/std/src/os/freebsd/net.rs26
-rw-r--r--library/std/src/os/netbsd/net.rs26
-rw-r--r--library/std/src/sys/pal/unix/net.rs31
3 files changed, 83 insertions, 0 deletions
diff --git a/library/std/src/os/freebsd/net.rs b/library/std/src/os/freebsd/net.rs
index 33990d54caa..b7e0fdc0a9a 100644
--- a/library/std/src/os/freebsd/net.rs
+++ b/library/std/src/os/freebsd/net.rs
@@ -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;
@@ -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")]
@@ -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")]
@@ -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)
+    }
 }
diff --git a/library/std/src/os/netbsd/net.rs b/library/std/src/os/netbsd/net.rs
index 5c82f43077d..b9679c7b3af 100644
--- a/library/std/src/os/netbsd/net.rs
+++ b/library/std/src/os/netbsd/net.rs
@@ -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;
@@ -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")]
@@ -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")]
@@ -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)
+    }
 }
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs
index 09750b6ffc8..1f140f7844f 100644
--- a/library/std/src/sys/pal/unix/net.rs
+++ b/library/std/src/sys/pal/unix/net.rs
@@ -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)