Skip to content
This repository has been archived by the owner on May 1, 2021. It is now read-only.

Commit

Permalink
Add VSOCK socket support
Browse files Browse the repository at this point in the history
Currently limited to Unix, but could be extended to Windows once the
AF_VSOCK API is bound.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
  • Loading branch information
elmarco committed Jan 11, 2021
1 parent 75e5f17 commit 4ec8787
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ readme = "README.md"

[target."cfg(unix)".dependencies]
libc = "0.2.77"
vsock = { version = "0.2.1", optional = true }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["handleapi", "ws2tcpip"] }
Expand Down
47 changes: 47 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ use {
winapi::um::ws2tcpip::socklen_t,
};

#[cfg(feature = "vsock")]
use vsock::VsockStream;

/// A raw socket address.
struct Addr {
storage: sockaddr_storage,
Expand Down Expand Up @@ -232,6 +235,50 @@ pub fn unix<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
unsafe { Ok(UnixStream::from_raw_fd(fd)) }
}

/// Creates a pending VSOCK connection to the specified path.
///
/// The returned stream will be in non-blocking mode and in the process of connecting to the
/// specified CID/port.
///
/// The stream becomes writable when connected.
///
/// # Examples
///
/// ```no_run
/// use polling::{Event, Poller};
/// use std::time::Duration;
///
/// // Create a pending VSOCK connection.
/// let stream = nb_connect::vsock(1, 9999)?;
///
/// // Create a poller that waits for the stream to become writable.
/// let poller = Poller::new()?;
/// poller.add(&stream, Event::writable(0))?;
///
/// // Wait for at most 1 second.
/// if poller.wait(&mut Vec::new(), Some(Duration::from_secs(1)))? == 0 {
/// println!("timeout");
/// } else {
/// println!("connected");
/// }
/// # std::io::Result::Ok(())
/// ```
#[cfg(all(unix, feature = "vsock"))]
pub fn vsock(cid: u32, port: u32) -> io::Result<VsockStream> {
let addr = unsafe {
let mut addr = mem::zeroed::<libc::sockaddr_vm>();
addr.svm_cid = cid;
addr.svm_port = port;
Addr::from_raw_parts(
&addr as *const _ as *const _,
mem::size_of::<libc::sockaddr_vm>() as u32,
)
};

let fd = connect(addr, libc::AF_VSOCK, 0)?;
unsafe { Ok(VsockStream::from_raw_fd(fd)) }
}

/// Creates a pending TCP connection to the specified address.
///
/// The returned TCP stream will be in non-blocking mode and in the process of connecting to the
Expand Down

0 comments on commit 4ec8787

Please sign in to comment.