Snap for 10453563 from 13c9ba703b10052628884ae3f02240c5c51180d1 to mainline-ipsec-release

Change-Id: I6d57c452c41c803e31c79f0e1ad07dae3995c6c7
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 3d9568d..906003c 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
 {
   "git": {
-    "sha1": "9b5e180bf04fd1d02db0c1e79c5ddd838dd42328"
-  }
-}
+    "sha1": "41d1faa752299f665d3ca429bf7a3d2367e7e774"
+  },
+  "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 17b9a91..10a6fa7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,7 +23,7 @@
     host_supported: true,
     crate_name: "vsock",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.2.6",
+    cargo_pkg_version: "0.3.0",
     srcs: ["src/lib.rs"],
     edition: "2018",
     rustlibs: [
@@ -32,6 +32,9 @@
     ],
     apex_available: [
         "//apex_available:platform",
+        "com.android.compos",
         "com.android.virt",
     ],
+    product_available: true,
+    vendor_available: true,
 }
diff --git a/Cargo.toml b/Cargo.toml
index 0002416..7cde53a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,19 +12,24 @@
 [package]
 edition = "2018"
 name = "vsock"
-version = "0.2.6"
-authors = ["fsyncd", "rust-vsock"]
+version = "0.3.0"
+authors = [
+    "fsyncd",
+    "rust-vsock",
+]
 exclude = ["test_fixture"]
 description = "Virtio socket support for Rust"
 homepage = "https://github.com/rust-vsock/vsock-rs"
 readme = "README.md"
 license = "Apache-2.0"
 repository = "https://github.com/rust-vsock/vsock-rs"
+
 [dependencies.libc]
-version = "0.2.79"
+version = "0.2.126"
 
 [dependencies.nix]
-version = "0.23.0"
+version = "0.24.2"
+
 [dev-dependencies.rand]
 version = "0.8.3"
 
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 7a6d39a..6b098e9 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "vsock"
-version = "0.2.6"
+version = "0.3.0"
 authors = ["fsyncd", "rust-vsock"]
 description = "Virtio socket support for Rust"
 repository = "https://github.com/rust-vsock/vsock-rs"
@@ -11,8 +11,8 @@
 exclude = ["test_fixture"]
 
 [dependencies]
-libc = "0.2.79"
-nix = "0.23.0"
+libc = "0.2.126"
+nix = "0.24.2"
 
 [dev-dependencies]
 rand = "0.8.3"
diff --git a/METADATA b/METADATA
index 768fa97..218588e 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/vsock/vsock-0.2.6.crate"
+    value: "https://static.crates.io/crates/vsock/vsock-0.3.0.crate"
   }
-  version: "0.2.6"
+  version: "0.3.0"
   license_type: NOTICE
   last_upgrade_date {
     year: 2022
-    month: 3
-    day: 1
+    month: 10
+    day: 6
   }
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
index b7c1df9..23589d9 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,19 +1,11 @@
 // Generated by update_crate_tests.py for tests that depend on this crate.
 {
-  "presubmit": [
+  "imports": [
     {
-      "name": "microdroid_manager_test"
+      "path": "packages/modules/Virtualization/microdroid_manager"
     },
     {
-      "name": "virtualizationservice_device_test"
-    }
-  ],
-  "presubmit-rust": [
-    {
-      "name": "microdroid_manager_test"
-    },
-    {
-      "name": "virtualizationservice_device_test"
+      "path": "packages/modules/Virtualization/virtualizationmanager"
     }
   ]
 }
diff --git a/cargo2android.json b/cargo2android.json
index 42b7833..07302e7 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -1,6 +1,7 @@
 {
   "apex-available": [
     "//apex_available:platform",
+    "com.android.compos",
     "com.android.virt"
   ],
   "dependencies": true,
diff --git a/src/lib.rs b/src/lib.rs
index aaeb393..e482e9f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -17,9 +17,19 @@
 
 //! Virtio socket support for Rust.
 
-use libc::*;
-use nix::ioctl_read_bad;
-use std::ffi::c_void;
+use libc::{
+    accept4, ioctl, sa_family_t, sockaddr, sockaddr_vm, socklen_t, suseconds_t, timeval, AF_VSOCK,
+    FIONBIO, SOCK_CLOEXEC,
+};
+use nix::{
+    ioctl_read_bad,
+    sys::socket::{
+        self, bind, connect, getpeername, getsockname, listen, recv, send, shutdown, socket,
+        sockopt::{ReceiveTimeout, SendTimeout, SocketError},
+        AddressFamily, GetSockOpt, MsgFlags, SetSockOpt, SockFlag, SockType,
+    },
+    unistd::close,
+};
 use std::fs::File;
 use std::io::{Error, ErrorKind, Read, Result, Write};
 use std::mem::{self, size_of};
@@ -28,10 +38,15 @@
 use std::time::Duration;
 
 pub use libc::{VMADDR_CID_ANY, VMADDR_CID_HOST, VMADDR_CID_HYPERVISOR, VMADDR_CID_LOCAL};
-pub use nix::sys::socket::{SockAddr, VsockAddr};
+pub use nix::sys::socket::{SockaddrLike, VsockAddr};
 
-fn new_socket() -> libc::c_int {
-    unsafe { socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC, 0) }
+fn new_socket() -> Result<RawFd> {
+    Ok(socket(
+        AddressFamily::Vsock,
+        SockType::Stream,
+        SockFlag::SOCK_CLOEXEC,
+        None,
+    )?)
 }
 
 /// An iterator that infinitely accepts connections on a VsockListener.
@@ -56,68 +71,32 @@
 
 impl VsockListener {
     /// Create a new VsockListener which is bound and listening on the socket address.
-    pub fn bind(addr: &SockAddr) -> Result<VsockListener> {
-        let mut vsock_addr = if let SockAddr::Vsock(addr) = addr {
-            addr.0
-        } else {
+    pub fn bind(addr: &impl SockaddrLike) -> Result<Self> {
+        if addr.family() != Some(AddressFamily::Vsock) {
             return Err(Error::new(
                 ErrorKind::Other,
                 "requires a virtio socket address",
             ));
-        };
-
-        let socket = new_socket();
-        if socket < 0 {
-            return Err(Error::last_os_error());
         }
 
-        let res = unsafe {
-            bind(
-                socket,
-                &mut vsock_addr as *mut _ as *mut sockaddr,
-                size_of::<sockaddr_vm>() as socklen_t,
-            )
-        };
-        if res < 0 {
-            return Err(Error::last_os_error());
-        }
+        let socket = new_socket()?;
+
+        bind(socket, addr)?;
 
         // rust stdlib uses a 128 connection backlog
-        let res = unsafe { listen(socket, 128) };
-        if res < 0 {
-            return Err(Error::last_os_error());
-        }
+        listen(socket, 128)?;
 
         Ok(Self { socket })
     }
 
     /// Create a new VsockListener with specified cid and port.
     pub fn bind_with_cid_port(cid: u32, port: u32) -> Result<VsockListener> {
-        Self::bind(&SockAddr::Vsock(VsockAddr::new(cid, port)))
+        Self::bind(&VsockAddr::new(cid, port))
     }
 
     /// The local socket address of the listener.
-    pub fn local_addr(&self) -> Result<SockAddr> {
-        let mut vsock_addr = sockaddr_vm {
-            svm_family: AF_VSOCK as sa_family_t,
-            svm_reserved1: 0,
-            svm_port: 0,
-            svm_cid: 0,
-            svm_zero: [0u8; 4],
-        };
-        let mut vsock_addr_len = size_of::<sockaddr_vm>() as socklen_t;
-        if unsafe {
-            getsockname(
-                self.socket,
-                &mut vsock_addr as *mut _ as *mut sockaddr,
-                &mut vsock_addr_len,
-            )
-        } < 0
-        {
-            Err(Error::last_os_error())
-        } else {
-            Ok(SockAddr::Vsock(VsockAddr(vsock_addr)))
-        }
+    pub fn local_addr(&self) -> Result<VsockAddr> {
+        Ok(getsockname(self.socket)?)
     }
 
     /// Create a new independently owned handle to the underlying socket.
@@ -126,7 +105,7 @@
     }
 
     /// Accept a new incoming connection from this listener.
-    pub fn accept(&self) -> Result<(VsockStream, SockAddr)> {
+    pub fn accept(&self) -> Result<(VsockStream, VsockAddr)> {
         let mut vsock_addr = sockaddr_vm {
             svm_family: AF_VSOCK as sa_family_t,
             svm_reserved1: 0,
@@ -148,7 +127,7 @@
         } else {
             Ok((
                 unsafe { VsockStream::from_raw_fd(socket as RawFd) },
-                SockAddr::Vsock(VsockAddr::new(vsock_addr.svm_cid, vsock_addr.svm_port)),
+                VsockAddr::new(vsock_addr.svm_cid, vsock_addr.svm_port),
             ))
         }
     }
@@ -160,26 +139,12 @@
 
     /// Retrieve the latest error associated with the underlying socket.
     pub fn take_error(&self) -> Result<Option<Error>> {
-        let mut error: i32 = 0;
-        let mut error_len: socklen_t = 0;
-        if unsafe {
-            getsockopt(
-                self.socket,
-                SOL_SOCKET,
-                SO_ERROR,
-                &mut error as *mut _ as *mut c_void,
-                &mut error_len,
-            )
-        } < 0
-        {
-            Err(Error::last_os_error())
+        let error = SocketError.get(self.socket)?;
+        Ok(if error == 0 {
+            None
         } else {
-            Ok(if error == 0 {
-                None
-            } else {
-                Some(Error::from_raw_os_error(error))
-            })
-        }
+            Some(Error::from_raw_os_error(error))
+        })
     }
 
     /// Move this stream in and out of nonblocking mode.
@@ -215,7 +180,7 @@
 
 impl Drop for VsockListener {
     fn drop(&mut self) {
-        unsafe { close(self.socket) };
+        let _ = close(self.socket);
     }
 }
 
@@ -227,99 +192,42 @@
 
 impl VsockStream {
     /// Open a connection to a remote host.
-    pub fn connect(addr: &SockAddr) -> Result<Self> {
-        let vsock_addr = if let SockAddr::Vsock(addr) = addr {
-            addr.0
-        } else {
+    pub fn connect(addr: &impl SockaddrLike) -> Result<Self> {
+        if addr.family() != Some(AddressFamily::Vsock) {
             return Err(Error::new(
                 ErrorKind::Other,
                 "requires a virtio socket address",
             ));
-        };
+        }
 
-        let sock = new_socket();
-        if sock < 0 {
-            return Err(Error::last_os_error());
-        }
-        if unsafe {
-            connect(
-                sock,
-                &vsock_addr as *const _ as *const sockaddr,
-                size_of::<sockaddr_vm>() as socklen_t,
-            )
-        } < 0
-        {
-            Err(Error::last_os_error())
-        } else {
-            Ok(unsafe { VsockStream::from_raw_fd(sock) })
-        }
+        let sock = new_socket()?;
+        connect(sock, addr)?;
+        Ok(unsafe { Self::from_raw_fd(sock) })
     }
 
     /// Open a connection to a remote host with specified cid and port.
     pub fn connect_with_cid_port(cid: u32, port: u32) -> Result<Self> {
-        Self::connect(&SockAddr::Vsock(VsockAddr::new(cid, port)))
+        Self::connect(&VsockAddr::new(cid, port))
     }
 
     /// Virtio socket address of the remote peer associated with this connection.
-    pub fn peer_addr(&self) -> Result<SockAddr> {
-        let mut vsock_addr = sockaddr_vm {
-            svm_family: AF_VSOCK as sa_family_t,
-            svm_reserved1: 0,
-            svm_port: 0,
-            svm_cid: 0,
-            svm_zero: [0u8; 4],
-        };
-        let mut vsock_addr_len = size_of::<sockaddr_vm>() as socklen_t;
-        if unsafe {
-            getpeername(
-                self.socket,
-                &mut vsock_addr as *mut _ as *mut sockaddr,
-                &mut vsock_addr_len,
-            )
-        } < 0
-        {
-            Err(Error::last_os_error())
-        } else {
-            Ok(SockAddr::Vsock(VsockAddr(vsock_addr)))
-        }
+    pub fn peer_addr(&self) -> Result<VsockAddr> {
+        Ok(getpeername(self.socket)?)
     }
 
     /// Virtio socket address of the local address associated with this connection.
-    pub fn local_addr(&self) -> Result<SockAddr> {
-        let mut vsock_addr = sockaddr_vm {
-            svm_family: AF_VSOCK as sa_family_t,
-            svm_reserved1: 0,
-            svm_port: 0,
-            svm_cid: 0,
-            svm_zero: [0u8; 4],
-        };
-        let mut vsock_addr_len = size_of::<sockaddr_vm>() as socklen_t;
-        if unsafe {
-            getsockname(
-                self.socket,
-                &mut vsock_addr as *mut _ as *mut sockaddr,
-                &mut vsock_addr_len,
-            )
-        } < 0
-        {
-            Err(Error::last_os_error())
-        } else {
-            Ok(SockAddr::Vsock(VsockAddr(vsock_addr)))
-        }
+    pub fn local_addr(&self) -> Result<VsockAddr> {
+        Ok(getsockname(self.socket)?)
     }
 
     /// Shutdown the read, write, or both halves of this connection.
     pub fn shutdown(&self, how: Shutdown) -> Result<()> {
         let how = match how {
-            Shutdown::Write => SHUT_WR,
-            Shutdown::Read => SHUT_RD,
-            Shutdown::Both => SHUT_RDWR,
+            Shutdown::Write => socket::Shutdown::Write,
+            Shutdown::Read => socket::Shutdown::Read,
+            Shutdown::Both => socket::Shutdown::Both,
         };
-        if unsafe { shutdown(self.socket, how) } < 0 {
-            Err(Error::last_os_error())
-        } else {
-            Ok(())
-        }
+        Ok(shutdown(self.socket, how)?)
     }
 
     /// Create a new independently owned handle to the underlying socket.
@@ -329,64 +237,24 @@
 
     /// Set the timeout on read operations.
     pub fn set_read_timeout(&self, dur: Option<Duration>) -> Result<()> {
-        let timeout = Self::timeval_from_duration(dur)?;
-        if unsafe {
-            setsockopt(
-                self.socket,
-                SOL_SOCKET,
-                SO_SNDTIMEO,
-                &timeout as *const _ as *const c_void,
-                size_of::<timeval>() as socklen_t,
-            )
-        } < 0
-        {
-            Err(Error::last_os_error())
-        } else {
-            Ok(())
-        }
+        let timeout = Self::timeval_from_duration(dur)?.into();
+        Ok(SendTimeout.set(self.socket, &timeout)?)
     }
 
     /// Set the timeout on write operations.
     pub fn set_write_timeout(&self, dur: Option<Duration>) -> Result<()> {
-        let timeout = Self::timeval_from_duration(dur)?;
-        if unsafe {
-            setsockopt(
-                self.socket,
-                SOL_SOCKET,
-                SO_RCVTIMEO,
-                &timeout as *const _ as *const c_void,
-                size_of::<timeval>() as socklen_t,
-            )
-        } < 0
-        {
-            Err(Error::last_os_error())
-        } else {
-            Ok(())
-        }
+        let timeout = Self::timeval_from_duration(dur)?.into();
+        Ok(ReceiveTimeout.set(self.socket, &timeout)?)
     }
 
     /// Retrieve the latest error associated with the underlying socket.
     pub fn take_error(&self) -> Result<Option<Error>> {
-        let mut error: i32 = 0;
-        let mut error_len: socklen_t = 0;
-        if unsafe {
-            getsockopt(
-                self.socket,
-                SOL_SOCKET,
-                SO_ERROR,
-                &mut error as *mut _ as *mut c_void,
-                &mut error_len,
-            )
-        } < 0
-        {
-            Err(Error::last_os_error())
+        let error = SocketError.get(self.socket)?;
+        Ok(if error == 0 {
+            None
         } else {
-            Ok(if error == 0 {
-                None
-            } else {
-                Some(Error::from_raw_os_error(error))
-            })
-        }
+            Some(Error::from_raw_os_error(error))
+        })
     }
 
     /// Move this stream in and out of nonblocking mode.
@@ -411,10 +279,10 @@
 
                 // https://github.com/rust-lang/libc/issues/1848
                 #[cfg_attr(target_env = "musl", allow(deprecated))]
-                let secs = if dur.as_secs() > time_t::max_value() as u64 {
-                    time_t::max_value()
+                let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
+                    libc::time_t::max_value()
                 } else {
-                    dur.as_secs() as time_t
+                    dur.as_secs() as libc::time_t
                 };
                 let mut timeout = timeval {
                     tv_sec: secs,
@@ -451,30 +319,13 @@
 
 impl Read for &VsockStream {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
-        let ret = unsafe { recv(self.socket, buf.as_mut_ptr() as *mut c_void, buf.len(), 0) };
-        if ret < 0 {
-            Err(Error::last_os_error())
-        } else {
-            Ok(ret as usize)
-        }
+        Ok(recv(self.socket, buf, MsgFlags::empty())?)
     }
 }
 
 impl Write for &VsockStream {
     fn write(&mut self, buf: &[u8]) -> Result<usize> {
-        let ret = unsafe {
-            send(
-                self.socket,
-                buf.as_ptr() as *const c_void,
-                buf.len(),
-                MSG_NOSIGNAL,
-            )
-        };
-        if ret < 0 {
-            Err(Error::last_os_error())
-        } else {
-            Ok(ret as usize)
-        }
+        Ok(send(self.socket, buf, MsgFlags::MSG_NOSIGNAL)?)
     }
 
     fn flush(&mut self) -> Result<()> {
@@ -504,7 +355,7 @@
 
 impl Drop for VsockStream {
     fn drop(&mut self) {
-        unsafe { close(self.socket) };
+        let _ = close(self.socket);
     }
 }
 
diff --git a/tests/vsock.rs b/tests/vsock.rs
index 52d908b..1ac60c9 100644
--- a/tests/vsock.rs
+++ b/tests/vsock.rs
@@ -17,11 +17,15 @@
 use rand::RngCore;
 use sha2::{Digest, Sha256};
 use std::io::{Read, Write};
-use vsock::{get_local_cid, SockAddr, VsockAddr, VsockStream, VMADDR_CID_HOST};
+use vsock::{get_local_cid, VsockAddr, VsockListener, VsockStream, VMADDR_CID_HOST};
 
 const TEST_BLOB_SIZE: usize = 1_000_000;
 const TEST_BLOCK_SIZE: usize = 5_000;
 
+const SERVER_CID: u32 = 3;
+const SERVER_PORT: u32 = 8000;
+const LISTEN_PORT: u32 = 9000;
+
 /// A simple test for the vsock implementation.
 /// Generate a large random blob of binary data, and transfer it in chunks over the VsockStream
 /// interface. The vm enpoint is running a simple echo server, so for each chunk we will read
@@ -40,7 +44,7 @@
     rng.fill_bytes(&mut blob);
 
     let mut stream =
-        VsockStream::connect(&SockAddr::Vsock(VsockAddr::new(3, 8000))).expect("connection failed");
+        VsockStream::connect(&VsockAddr::new(SERVER_CID, SERVER_PORT)).expect("connection failed");
 
     while tx_pos < TEST_BLOB_SIZE {
         let written_bytes = stream
@@ -72,3 +76,27 @@
 fn test_get_local_cid() {
     assert_eq!(get_local_cid().unwrap(), VMADDR_CID_HOST);
 }
+
+#[test]
+fn test_listener_local_addr() {
+    let listener = VsockListener::bind(&VsockAddr::new(VMADDR_CID_HOST, LISTEN_PORT)).unwrap();
+
+    let local_addr = listener.local_addr().unwrap();
+    assert_eq!(local_addr.cid(), VMADDR_CID_HOST);
+    assert_eq!(local_addr.port(), LISTEN_PORT);
+}
+
+#[test]
+fn test_stream_addresses() {
+    let stream =
+        VsockStream::connect(&VsockAddr::new(SERVER_CID, SERVER_PORT)).expect("connection failed");
+
+    let local_addr = stream.local_addr().unwrap();
+    // Apparently on some systems a client socket has the host CID, on some it has CID_ANY. Allow
+    // either.
+    assert!([libc::VMADDR_CID_ANY, VMADDR_CID_HOST].contains(&local_addr.cid()));
+
+    let peer_addr = stream.peer_addr().unwrap();
+    assert_eq!(peer_addr.cid(), SERVER_CID);
+    assert_eq!(peer_addr.port(), SERVER_PORT);
+}