Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 29 additions & 28 deletions src/devices/src/virtio/net/unixgram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,40 @@ pub struct Unixgram {
impl Unixgram {
/// Create the backend with a pre-established connection to the userspace network proxy.
pub fn new(fd: RawFd) -> Self {
// Ensure the socket is in non-blocking mode.
match fcntl(fd, FcntlArg::F_GETFL) {
Ok(flags) => match OFlag::from_bits(flags) {
Some(flags) => {
if let Err(e) = fcntl(fd, FcntlArg::F_SETFL(flags | OFlag::O_NONBLOCK)) {
warn!("error switching to non-blocking: id={fd}, err={e}");
}
}
None => error!("invalid fd flags id={fd}"),
},
Err(e) => error!("couldn't obtain fd flags id={fd}, err={e}"),
};

#[cfg(target_os = "macos")]
{
// nix doesn't provide an abstraction for SO_NOSIGPIPE, fall back to libc.
let option_value: libc::c_int = 1;
unsafe {
libc::setsockopt(
fd,
libc::SOL_SOCKET,
libc::SO_NOSIGPIPE,
&option_value as *const _ as *const libc::c_void,
std::mem::size_of_val(&option_value) as libc::socklen_t,
)
};
}

Self { fd }
}

/// Create the backend opening a connection to the userspace network proxy.
pub fn open(path: PathBuf, send_vfkit_magic: bool) -> Result<Self, ConnectError> {
// We cannot create a non-blocking socket on macOS here. This is done later in new().
let fd = socket(
AddressFamily::Unix,
SockType::Datagram,
Expand All @@ -47,34 +76,6 @@ impl Unixgram {
send(fd, &VFKIT_MAGIC, MsgFlags::empty()).map_err(ConnectError::SendingMagic)?;
}

// macOS forces us to do this here instead of just using SockFlag::SOCK_NONBLOCK above.
match fcntl(fd, FcntlArg::F_GETFL) {
Ok(flags) => match OFlag::from_bits(flags) {
Some(flags) => {
if let Err(e) = fcntl(fd, FcntlArg::F_SETFL(flags | OFlag::O_NONBLOCK)) {
warn!("error switching to non-blocking: id={fd}, err={e}");
}
}
None => error!("invalid fd flags id={fd}"),
},
Err(e) => error!("couldn't obtain fd flags id={fd}, err={e}"),
};

#[cfg(target_os = "macos")]
{
// nix doesn't provide an abstraction for SO_NOSIGPIPE, fall back to libc.
let option_value: libc::c_int = 1;
unsafe {
libc::setsockopt(
fd,
libc::SOL_SOCKET,
libc::SO_NOSIGPIPE,
&option_value as *const _ as *const libc::c_void,
std::mem::size_of_val(&option_value) as libc::socklen_t,
)
};
}

if let Err(e) = setsockopt(fd, sockopt::SndBuf, &(7 * 1024 * 1024)) {
log::warn!("Failed to increase SO_SNDBUF (performance may be decreased): {e}");
}
Expand Down
Loading