Skip to content

Commit 3a23e41

Browse files
socket: add support for AF_VSOCK
This patch add AF_VSOCK support to AddressFamily in order to use VSOCK socket. Signed-off-by: Stefano Garzarella <[email protected]>
1 parent 7fa4f23 commit 3a23e41

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1313
([#1069](https://github.com/nix-rust/nix/pull/1069))
1414
- Add `mkdirat`.
1515
([#1084](https://github.com/nix-rust/nix/pull/1084))
16+
- Added `AF_VSOCK` to `AddressFamily`.
17+
([#1091](https://github.com/nix-rust/nix/pull/1091))
1618

1719
### Changed
1820
- Support for `ifaddrs` now present when building for Android.

src/sys/socket/addr.rs

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ use ::sys::socket::addr::sys_control::SysControlAddr;
2424
target_os = "netbsd",
2525
target_os = "openbsd"))]
2626
pub use self::datalink::LinkAddr;
27+
#[cfg(target_os = "linux")]
28+
pub use self::vsock::VsockAddr;
2729

2830
/// These constants specify the protocol family to be used
2931
/// in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
@@ -241,6 +243,8 @@ impl AddressFamily {
241243
target_os = "netbsd",
242244
target_os = "openbsd"))]
243245
libc::AF_LINK => Some(AddressFamily::Link),
246+
#[cfg(target_os = "linux")]
247+
libc::AF_VSOCK => Some(AddressFamily::Vsock),
244248
_ => None
245249
}
246250
}
@@ -638,7 +642,9 @@ pub enum SockAddr {
638642
target_os = "macos",
639643
target_os = "netbsd",
640644
target_os = "openbsd"))]
641-
Link(LinkAddr)
645+
Link(LinkAddr),
646+
#[cfg(target_os = "linux")]
647+
Vsock(VsockAddr),
642648
}
643649

644650
impl SockAddr {
@@ -665,6 +671,11 @@ impl SockAddr {
665671
SysControlAddr::from_name(sockfd, name, unit).map(|a| SockAddr::SysControl(a))
666672
}
667673

674+
#[cfg(target_os = "linux")]
675+
pub fn new_vsock(cid: u32, port: u32) -> SockAddr {
676+
SockAddr::Vsock(VsockAddr::new(cid, port))
677+
}
678+
668679
pub fn family(&self) -> AddressFamily {
669680
match *self {
670681
SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet,
@@ -684,7 +695,9 @@ impl SockAddr {
684695
target_os = "macos",
685696
target_os = "netbsd",
686697
target_os = "openbsd"))]
687-
SockAddr::Link(..) => AddressFamily::Link
698+
SockAddr::Link(..) => AddressFamily::Link,
699+
#[cfg(target_os = "linux")]
700+
SockAddr::Vsock(..) => AddressFamily::Vsock,
688701
}
689702
}
690703

@@ -729,6 +742,9 @@ impl SockAddr {
729742
Some(SockAddr::Link(ether_addr))
730743
}
731744
},
745+
#[cfg(target_os = "linux")]
746+
Some(AddressFamily::Vsock) => Some(SockAddr::Vsock(
747+
VsockAddr(*(addr as *const libc::sockaddr_vm)))),
732748
// Other address families are currently not supported and simply yield a None
733749
// entry instead of a proper conversion to a `SockAddr`.
734750
Some(_) | None => None,
@@ -763,6 +779,8 @@ impl SockAddr {
763779
target_os = "netbsd",
764780
target_os = "openbsd"))]
765781
SockAddr::Link(LinkAddr(ref ether_addr)) => (mem::transmute(ether_addr), mem::size_of::<libc::sockaddr_dl>() as libc::socklen_t),
782+
#[cfg(target_os = "linux")]
783+
SockAddr::Vsock(VsockAddr(ref sa)) => (mem::transmute(sa), mem::size_of::<libc::sockaddr_vm>() as libc::socklen_t),
766784
}
767785
}
768786
}
@@ -786,7 +804,9 @@ impl fmt::Display for SockAddr {
786804
target_os = "macos",
787805
target_os = "netbsd",
788806
target_os = "openbsd"))]
789-
SockAddr::Link(ref ether_addr) => ether_addr.fmt(f)
807+
SockAddr::Link(ref ether_addr) => ether_addr.fmt(f),
808+
#[cfg(target_os = "linux")]
809+
SockAddr::Vsock(ref svm) => svm.fmt(f),
790810
}
791811
}
792812
}
@@ -1124,6 +1144,66 @@ mod datalink {
11241144
}
11251145
}
11261146

1147+
#[cfg(target_os = "linux")]
1148+
pub mod vsock {
1149+
use ::sys::socket::addr::AddressFamily;
1150+
use libc::{sa_family_t, sockaddr_vm};
1151+
use std::{fmt, mem};
1152+
use std::hash::{Hash, Hasher};
1153+
1154+
#[derive(Copy, Clone)]
1155+
pub struct VsockAddr(pub sockaddr_vm);
1156+
1157+
// , PartialEq, Eq, Debug, Hash
1158+
impl PartialEq for VsockAddr {
1159+
fn eq(&self, other: &Self) -> bool {
1160+
let (inner, other) = (self.0, other.0);
1161+
(inner.svm_family, inner.svm_cid, inner.svm_port) ==
1162+
(other.svm_family, other.svm_cid, other.svm_port)
1163+
}
1164+
}
1165+
1166+
impl Eq for VsockAddr {}
1167+
1168+
impl Hash for VsockAddr {
1169+
fn hash<H: Hasher>(&self, s: &mut H) {
1170+
let inner = self.0;
1171+
(inner.svm_family, inner.svm_cid, inner.svm_port).hash(s);
1172+
}
1173+
}
1174+
1175+
impl VsockAddr {
1176+
pub fn new(cid: u32, port: u32) -> VsockAddr {
1177+
let mut addr: sockaddr_vm = unsafe { mem::zeroed() };
1178+
addr.svm_family = AddressFamily::Vsock as sa_family_t;
1179+
addr.svm_cid = cid;
1180+
addr.svm_port = port;
1181+
1182+
VsockAddr(addr)
1183+
}
1184+
1185+
pub fn cid(&self) -> u32 {
1186+
self.0.svm_cid
1187+
}
1188+
1189+
pub fn port(&self) -> u32 {
1190+
self.0.svm_port
1191+
}
1192+
}
1193+
1194+
impl fmt::Display for VsockAddr {
1195+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1196+
write!(f, "cid: {} port: {}", self.cid(), self.port())
1197+
}
1198+
}
1199+
1200+
impl fmt::Debug for VsockAddr {
1201+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1202+
fmt::Display::fmt(self, f)
1203+
}
1204+
}
1205+
}
1206+
11271207
#[cfg(test)]
11281208
mod tests {
11291209
#[cfg(any(target_os = "android",

src/sys/socket/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pub use self::addr::{
3333
pub use ::sys::socket::addr::netlink::NetlinkAddr;
3434
#[cfg(any(target_os = "android", target_os = "linux"))]
3535
pub use sys::socket::addr::alg::AlgAddr;
36+
#[cfg(target_os = "linux")]
37+
pub use sys::socket::addr::vsock::VsockAddr;
3638

3739
pub use libc::{
3840
cmsghdr,
@@ -1254,6 +1256,11 @@ pub unsafe fn sockaddr_storage_to_addr(
12541256
use libc::sockaddr_alg;
12551257
Ok(SockAddr::Alg(AlgAddr(*(addr as *const _ as *const sockaddr_alg))))
12561258
}
1259+
#[cfg(target_os = "linux")]
1260+
libc::AF_VSOCK => {
1261+
use libc::sockaddr_vm;
1262+
Ok(SockAddr::Vsock(VsockAddr(*(addr as *const _ as *const sockaddr_vm))))
1263+
}
12571264
af => panic!("unexpected address family {}", af),
12581265
}
12591266
}

0 commit comments

Comments
 (0)