Skip to content

Commit 6d5e426

Browse files
committed
changes from feedback
1 parent c005f3e commit 6d5e426

File tree

3 files changed

+79
-23
lines changed

3 files changed

+79
-23
lines changed

src/sys/socket/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2466,7 +2466,7 @@ pub trait GetSockOpt: Copy {
24662466

24672467
/// Represents a socket option that can be set.
24682468
pub trait SetSockOpt: Clone {
2469-
type Val;
2469+
type Val: ?Sized;
24702470

24712471
/// Set the value of this socket option on the given socket.
24722472
fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()>;

src/sys/socket/sockopt.rs

+55-22
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Socket options as used by `setsockopt` and `getsockopt`.
2-
#[cfg(linux_android)]
2+
#[cfg(any(linux_android, target_os = "illumos"))]
33
use super::SetSockOpt;
44
use crate::sys::time::TimeVal;
5-
#[cfg(linux_android)]
5+
#[cfg(any(linux_android, target_os = "illumos"))]
66
use crate::{errno::Errno, Result};
77
use cfg_if::cfg_if;
88
use libc::{self, c_int, c_void, socklen_t};
@@ -11,7 +11,7 @@ use std::ffi::CString;
1111
use std::ffi::{CStr, OsStr, OsString};
1212
use std::mem::{self, MaybeUninit};
1313
use std::os::unix::ffi::OsStrExt;
14-
#[cfg(linux_android)]
14+
#[cfg(any(linux_android, target_os = "illumos"))]
1515
use std::os::unix::io::{AsFd, AsRawFd};
1616

1717
// Constants
@@ -987,25 +987,6 @@ sockopt_impl!(
987987
libc::SO_ACCEPTFILTER,
988988
libc::accept_filter_arg
989989
);
990-
#[cfg(target_os = "illumos")]
991-
sockopt_impl!(
992-
/// Attach a named filter to this socket to be able to
993-
/// defer when anough byte had been buffered by the kernel
994-
FilAttach,
995-
SetOnly,
996-
libc::SOL_FILTER,
997-
libc::FIL_ATTACH,
998-
SetOsString<'static>
999-
);
1000-
#[cfg(target_os = "illumos")]
1001-
sockopt_impl!(
1002-
/// Detach a socket filter previously attached with FIL_ATTACH
1003-
FilDetach,
1004-
SetOnly,
1005-
libc::SOL_FILTER,
1006-
libc::FIL_DETACH,
1007-
SetOsString<'static>
1008-
);
1009990
#[cfg(target_os = "linux")]
1010991
sockopt_impl!(
1011992
/// Set the mark for each packet sent through this socket (similar to the
@@ -1501,6 +1482,58 @@ impl SetSockOpt for TcpTlsRx {
15011482
}
15021483
}
15031484

1485+
#[cfg(target_os = "illumos")]
1486+
#[derive(Copy, Clone, Debug)]
1487+
/// Attach a named filter to this socket to be able to
1488+
/// defer when anough byte had been buffered by the kernel
1489+
pub struct FilterAttach;
1490+
1491+
#[cfg(target_os = "illumos")]
1492+
impl SetSockOpt for FilterAttach {
1493+
type Val = OsStr;
1494+
1495+
fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()> {
1496+
if val.len() > libc::FILNAME_MAX as usize {
1497+
return Err(Errno::EINVAL);
1498+
}
1499+
unsafe {
1500+
let res = libc::setsockopt(
1501+
fd.as_fd().as_raw_fd(),
1502+
libc::SOL_FILTER,
1503+
libc::FIL_ATTACH,
1504+
val.as_bytes().as_ptr().cast(),
1505+
val.len() as libc::socklen_t,
1506+
);
1507+
Errno::result(res).map(drop)
1508+
}
1509+
}
1510+
}
1511+
1512+
#[cfg(target_os = "illumos")]
1513+
#[derive(Copy, Clone, Debug)]
1514+
/// Detach a socket filter previously attached with FIL_ATTACH
1515+
pub struct FilterDetach;
1516+
1517+
#[cfg(target_os = "illumos")]
1518+
impl SetSockOpt for FilterDetach {
1519+
type Val = OsStr;
1520+
1521+
fn set<F: AsFd>(&self, fd: &F, val: &Self::Val) -> Result<()> {
1522+
if val.len() > libc::FILNAME_MAX as usize {
1523+
return Err(Errno::EINVAL);
1524+
}
1525+
unsafe {
1526+
let res = libc::setsockopt(
1527+
fd.as_fd().as_raw_fd(),
1528+
libc::SOL_FILTER,
1529+
libc::FIL_DETACH,
1530+
val.as_bytes().as_ptr().cast(),
1531+
val.len() as libc::socklen_t,
1532+
);
1533+
Errno::result(res).map(drop)
1534+
}
1535+
}
1536+
}
15041537
/*
15051538
*
15061539
* ===== Accessor helpers =====

test/sys/test_sockopt.rs

+23
Original file line numberDiff line numberDiff line change
@@ -1168,3 +1168,26 @@ fn test_exclbind() {
11681168
Err(Errno::EADDRINUSE)
11691169
);
11701170
}
1171+
1172+
#[cfg(target_os = "illumos")]
1173+
#[test]
1174+
fn test_solfilter() {
1175+
use nix::errno::Errno;
1176+
let s = socket(
1177+
AddressFamily::Inet,
1178+
SockType::Stream,
1179+
SockFlag::empty(),
1180+
SockProtocol::Tcp,
1181+
)
1182+
.unwrap();
1183+
let data = std::ffi::OsStr::new("httpf");
1184+
let attach = sockopt::FilterAttach;
1185+
let detach = sockopt::FilterDetach;
1186+
1187+
// These 2 options won't work unless the needed kernel module is installed:
1188+
// https://github.com/nix-rust/nix/pull/2611#issuecomment-2750237782
1189+
//
1190+
// So we only test the binding here
1191+
assert_eq!(Err(Errno::ENOENT), setsockopt(&s, attach, data));
1192+
assert_eq!(Err(Errno::ENOENT), setsockopt(&s, detach, data));
1193+
}

0 commit comments

Comments
 (0)