Skip to content

Commit 7b892bf

Browse files
committed
add vsock support for macOS
1 parent 89b4976 commit 7b892bf

File tree

4 files changed

+72
-12
lines changed

4 files changed

+72
-12
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ targets = [
2727
]
2828

2929
[dependencies]
30-
libc = { version = "0.2.141", features = ["extra_traits"] }
30+
libc = { version = "0.2.146", features = ["extra_traits"] }
3131
bitflags = "1.1"
3232
cfg-if = "1.0"
3333
pin-utils = { version = "0.1.0", optional = true }

src/sys/socket/addr.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
))]
1414
#[cfg(feature = "net")]
1515
pub use self::datalink::LinkAddr;
16-
#[cfg(any(target_os = "android", target_os = "linux"))]
16+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
1717
pub use self::vsock::VsockAddr;
1818
use super::sa_family_t;
1919
use crate::errno::Errno;
@@ -249,7 +249,7 @@ pub enum AddressFamily {
249249
#[cfg_attr(docsrs, doc(cfg(all())))]
250250
Nfc = libc::AF_NFC,
251251
/// VMWare VSockets protocol for hypervisor-guest interaction.
252-
#[cfg(any(target_os = "android", target_os = "linux"))]
252+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
253253
#[cfg_attr(docsrs, doc(cfg(all())))]
254254
Vsock = libc::AF_VSOCK,
255255
/// ARPANet IMP addresses
@@ -444,7 +444,7 @@ impl AddressFamily {
444444
target_os = "openbsd"
445445
))]
446446
libc::AF_LINK => Some(AddressFamily::Link),
447-
#[cfg(any(target_os = "android", target_os = "linux"))]
447+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
448448
libc::AF_VSOCK => Some(AddressFamily::Vsock),
449449
_ => None,
450450
}
@@ -1246,7 +1246,7 @@ pub union SockaddrStorage {
12461246
sin6: SockaddrIn6,
12471247
ss: libc::sockaddr_storage,
12481248
su: UnixAddr,
1249-
#[cfg(any(target_os = "android", target_os = "linux"))]
1249+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos" ))]
12501250
#[cfg_attr(docsrs, doc(cfg(all())))]
12511251
vsock: VsockAddr,
12521252
}
@@ -1338,7 +1338,7 @@ impl SockaddrLike for SockaddrStorage {
13381338
libc::AF_SYSTEM => {
13391339
SysControlAddr::from_raw(addr, l).map(|sctl| Self { sctl })
13401340
}
1341-
#[cfg(any(target_os = "android", target_os = "linux"))]
1341+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos" ))]
13421342
libc::AF_VSOCK => {
13431343
VsockAddr::from_raw(addr, l).map(|vsock| Self { vsock })
13441344
}
@@ -1505,7 +1505,7 @@ impl SockaddrStorage {
15051505
accessors! {as_sys_control_addr, as_sys_control_addr_mut, SysControlAddr,
15061506
AddressFamily::System, libc::sockaddr_ctl, sctl}
15071507

1508-
#[cfg(any(target_os = "android", target_os = "linux"))]
1508+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
15091509
#[cfg_attr(docsrs, doc(cfg(all())))]
15101510
accessors! {as_vsock_addr, as_vsock_addr_mut, VsockAddr,
15111511
AddressFamily::Vsock, libc::sockaddr_vm, vsock}
@@ -1555,7 +1555,7 @@ impl fmt::Display for SockaddrStorage {
15551555
#[cfg(feature = "ioctl")]
15561556
libc::AF_SYSTEM => self.sctl.fmt(f),
15571557
libc::AF_UNIX => self.su.fmt(f),
1558-
#[cfg(any(target_os = "android", target_os = "linux"))]
1558+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
15591559
libc::AF_VSOCK => self.vsock.fmt(f),
15601560
_ => "<Address family unspecified>".fmt(f),
15611561
}
@@ -1629,7 +1629,7 @@ impl Hash for SockaddrStorage {
16291629
#[cfg(feature = "ioctl")]
16301630
libc::AF_SYSTEM => self.sctl.hash(s),
16311631
libc::AF_UNIX => self.su.hash(s),
1632-
#[cfg(any(target_os = "android", target_os = "linux"))]
1632+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
16331633
libc::AF_VSOCK => self.vsock.hash(s),
16341634
_ => self.ss.hash(s),
16351635
}
@@ -1671,7 +1671,7 @@ impl PartialEq for SockaddrStorage {
16711671
#[cfg(feature = "ioctl")]
16721672
(libc::AF_SYSTEM, libc::AF_SYSTEM) => self.sctl == other.sctl,
16731673
(libc::AF_UNIX, libc::AF_UNIX) => self.su == other.su,
1674-
#[cfg(any(target_os = "android", target_os = "linux"))]
1674+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
16751675
(libc::AF_VSOCK, libc::AF_VSOCK) => self.vsock == other.vsock,
16761676
_ => false,
16771677
}
@@ -2220,7 +2220,7 @@ mod datalink {
22202220
}
22212221
}
22222222

2223-
#[cfg(any(target_os = "android", target_os = "linux"))]
2223+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
22242224
#[cfg_attr(docsrs, doc(cfg(all())))]
22252225
pub mod vsock {
22262226
use super::*;
@@ -2266,20 +2266,33 @@ pub mod vsock {
22662266
}
22672267

22682268
impl PartialEq for VsockAddr {
2269+
#[cfg(any(target_os = "android", target_os = "linux"))]
22692270
fn eq(&self, other: &Self) -> bool {
22702271
let (inner, other) = (self.0, other.0);
22712272
(inner.svm_family, inner.svm_cid, inner.svm_port)
22722273
== (other.svm_family, other.svm_cid, other.svm_port)
22732274
}
2275+
#[cfg(target_os = "macos")]
2276+
fn eq(&self, other: &Self) -> bool {
2277+
let (inner, other) = (self.0, other.0);
2278+
(inner.svm_family, inner.svm_cid, inner.svm_port, inner.svm_len)
2279+
== (other.svm_family, other.svm_cid, other.svm_port, inner.svm_len)
2280+
}
22742281
}
22752282

22762283
impl Eq for VsockAddr {}
22772284

22782285
impl Hash for VsockAddr {
2286+
#[cfg(any(target_os = "android", target_os = "linux"))]
22792287
fn hash<H: Hasher>(&self, s: &mut H) {
22802288
let inner = self.0;
22812289
(inner.svm_family, inner.svm_cid, inner.svm_port).hash(s);
22822290
}
2291+
#[cfg(target_os = "macos")]
2292+
fn hash<H: Hasher>(&self, s: &mut H) {
2293+
let inner = self.0;
2294+
(inner.svm_family, inner.svm_cid, inner.svm_port, inner.svm_len).hash(s);
2295+
}
22832296
}
22842297

22852298
/// VSOCK Address
@@ -2294,6 +2307,10 @@ pub mod vsock {
22942307
addr.svm_cid = cid;
22952308
addr.svm_port = port;
22962309

2310+
#[cfg(target_os = "macos")]
2311+
{
2312+
addr.svm_len = std::mem::size_of::<sockaddr_vm>() as u8;
2313+
}
22972314
VsockAddr(addr)
22982315
}
22992316

src/sys/socket/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub use crate::sys::socket::addr::netlink::NetlinkAddr;
6262
#[cfg(any(target_os = "ios", target_os = "macos"))]
6363
#[cfg(feature = "ioctl")]
6464
pub use crate::sys::socket::addr::sys_control::SysControlAddr;
65-
#[cfg(any(target_os = "android", target_os = "linux"))]
65+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
6666
pub use crate::sys::socket::addr::vsock::VsockAddr;
6767

6868
#[cfg(all(feature = "uio", not(target_os = "redox")))]

test/sys/test_socket.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,6 +2079,49 @@ pub fn test_vsock() {
20792079
assert_eq!(addr3.as_ref().svm_port, addr1.port());
20802080
}
20812081

2082+
#[cfg(target_os = "macos")]
2083+
#[test]
2084+
pub fn test_vsock() {
2085+
use nix::sys::socket::SockaddrLike;
2086+
use nix::sys::socket::{AddressFamily, VsockAddr};
2087+
use std::mem;
2088+
2089+
let port: u32 = 3000;
2090+
2091+
// macOS doesn't have a VMADDR_CID_LOCAL, so test with host again
2092+
let addr_host = VsockAddr::new(libc::VMADDR_CID_HOST, port);
2093+
assert_eq!(addr_host.cid(), libc::VMADDR_CID_HOST);
2094+
assert_eq!(addr_host.port(), port);
2095+
2096+
let addr_any = VsockAddr::new(libc::VMADDR_CID_ANY, libc::VMADDR_PORT_ANY);
2097+
assert_eq!(addr_any.cid(), libc::VMADDR_CID_ANY);
2098+
assert_eq!(addr_any.port(), libc::VMADDR_PORT_ANY);
2099+
2100+
assert_ne!(addr_host, addr_any);
2101+
assert_ne!(calculate_hash(&addr_host), calculate_hash(&addr_any));
2102+
2103+
let addr1 = VsockAddr::new(libc::VMADDR_CID_HOST, port);
2104+
let addr2 = VsockAddr::new(libc::VMADDR_CID_HOST, port);
2105+
assert_eq!(addr1, addr2);
2106+
assert_eq!(calculate_hash(&addr1), calculate_hash(&addr2));
2107+
2108+
let addr3 = unsafe {
2109+
VsockAddr::from_raw(
2110+
addr2.as_ref() as *const libc::sockaddr_vm as *const libc::sockaddr,
2111+
Some(mem::size_of::<libc::sockaddr_vm>().try_into().unwrap()),
2112+
)
2113+
}
2114+
.unwrap();
2115+
assert_eq!(
2116+
addr3.as_ref().svm_family,
2117+
AddressFamily::Vsock as libc::sa_family_t
2118+
);
2119+
let cid = addr3.as_ref().svm_cid;
2120+
let port = addr3.as_ref().svm_port;
2121+
assert_eq!(cid, addr1.cid());
2122+
assert_eq!(port, addr1.port());
2123+
}
2124+
20822125
// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack
20832126
// of QEMU support is suspected.
20842127
#[cfg_attr(qemu, ignore)]

0 commit comments

Comments
 (0)