diff options
author | Alyssa Ross <hi@alyssa.is> | 2020-03-20 05:48:28 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2020-06-15 09:37:05 +0000 |
commit | 8214c4c64fbdbf6ae84634bb822a90959271cad5 (patch) | |
tree | 6d46db38cb233ae7a7cf592b485608af96accf12 /msg_socket2/src | |
parent | b76f0d1043ffde3c6525abaecb421c0a4dc4c277 (diff) | |
download | crosvm-8214c4c64fbdbf6ae84634bb822a90959271cad5.tar crosvm-8214c4c64fbdbf6ae84634bb822a90959271cad5.tar.gz crosvm-8214c4c64fbdbf6ae84634bb822a90959271cad5.tar.bz2 crosvm-8214c4c64fbdbf6ae84634bb822a90959271cad5.tar.lz crosvm-8214c4c64fbdbf6ae84634bb822a90959271cad5.tar.xz crosvm-8214c4c64fbdbf6ae84634bb822a90959271cad5.tar.zst crosvm-8214c4c64fbdbf6ae84634bb822a90959271cad5.zip |
msg_socket2: initial commit
Diffstat (limited to 'msg_socket2/src')
-rw-r--r-- | msg_socket2/src/de.rs | 21 | ||||
-rw-r--r-- | msg_socket2/src/error.rs | 23 | ||||
-rw-r--r-- | msg_socket2/src/lib.rs | 34 | ||||
-rw-r--r-- | msg_socket2/src/ser.rs | 20 | ||||
-rw-r--r-- | msg_socket2/src/socket.rs | 48 |
5 files changed, 146 insertions, 0 deletions
diff --git a/msg_socket2/src/de.rs b/msg_socket2/src/de.rs new file mode 100644 index 0000000..1d3a9e1 --- /dev/null +++ b/msg_socket2/src/de.rs @@ -0,0 +1,21 @@ +use serde::Deserializer; +use std::os::unix::prelude::*; + +pub trait DeserializeWithFds<'de>: Sized { + fn deserialize<I, De>(deserializer: DeserializerWithFds<I, De>) -> Result<Self, De::Error> + where + I: Iterator<Item = RawFd>, + De: Deserializer<'de>; +} + +#[derive(Debug)] +pub struct DeserializerWithFds<'iter, Iter, De> { + pub deserializer: De, + pub fds: &'iter mut Iter, +} + +impl<'iter, Iter, De> DeserializerWithFds<'iter, Iter, De> { + pub fn new(fds: &'iter mut Iter, deserializer: De) -> Self { + Self { deserializer, fds } + } +} diff --git a/msg_socket2/src/error.rs b/msg_socket2/src/error.rs new file mode 100644 index 0000000..902684b --- /dev/null +++ b/msg_socket2/src/error.rs @@ -0,0 +1,23 @@ +#[derive(Debug)] +pub enum Error { + DataError(bincode::Error), + IoError(sys_util::Error), +} + +impl From<bincode::Error> for Error { + fn from(error: bincode::Error) -> Self { + Self::DataError(error) + } +} + +impl From<sys_util::Error> for Error { + fn from(error: sys_util::Error) -> Self { + Self::IoError(error) + } +} + +impl From<std::io::Error> for Error { + fn from(error: std::io::Error) -> Self { + Self::IoError(error.into()) + } +} diff --git a/msg_socket2/src/lib.rs b/msg_socket2/src/lib.rs new file mode 100644 index 0000000..748a9f7 --- /dev/null +++ b/msg_socket2/src/lib.rs @@ -0,0 +1,34 @@ +// Copyright 2020, Alyssa Ross +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the <organization> nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +mod de; +mod error; +mod ser; +mod socket; + +pub use de::{DeserializeWithFds, DeserializerWithFds}; +pub use error::Error; +pub use ser::{SerializeWithFds, SerializerWithFds}; +pub use socket::Socket; diff --git a/msg_socket2/src/ser.rs b/msg_socket2/src/ser.rs new file mode 100644 index 0000000..0a60ea8 --- /dev/null +++ b/msg_socket2/src/ser.rs @@ -0,0 +1,20 @@ +use serde::Serializer; +use std::os::unix::prelude::*; + +pub trait SerializeWithFds { + fn serialize<Ser>(&self, serializer: SerializerWithFds<Ser>) -> Result<Ser::Ok, Ser::Error> + where + Ser: Serializer; +} + +#[derive(Debug)] +pub struct SerializerWithFds<'fds, Ser> { + pub serializer: Ser, + pub fds: &'fds mut Vec<RawFd>, +} + +impl<'fds, Ser> SerializerWithFds<'fds, Ser> { + pub fn new(fds: &'fds mut Vec<RawFd>, serializer: Ser) -> Self { + Self { serializer, fds } + } +} diff --git a/msg_socket2/src/socket.rs b/msg_socket2/src/socket.rs new file mode 100644 index 0000000..bce587a --- /dev/null +++ b/msg_socket2/src/socket.rs @@ -0,0 +1,48 @@ +use bincode::{DefaultOptions, Serializer, Deserializer}; +use std::marker::PhantomData; +use std::io::IoSlice; +use sys_util::{net::UnixSeqpacket, ScmSocket}; + +use crate::{DeserializerWithFds, DeserializeWithFds, Error, SerializeWithFds, SerializerWithFds}; + +#[derive(Debug)] +pub struct Socket<Send, Recv> { + sock: UnixSeqpacket, + __: PhantomData<(Send, Recv)>, +} + +impl<Send, Recv> Socket<Send, Recv> { + pub fn new(sock: UnixSeqpacket) -> Self { + Self { + sock, + __: PhantomData, + } + } +} + +impl<Send: SerializeWithFds, Recv> Socket<Send, Recv> { + pub fn send(&self, value: Send) -> Result<(), Error> { + let mut bytes: Vec<u8> = vec![]; + let mut fds: Vec<RawFd> = vec![]; + + let mut serializer = Serializer::new(&mut bytes, DefaultOptions::new()); + let serializer_with_fds = SerializerWithFds::new(&mut fds, &mut serializer); + value.serialize(serializer_with_fds)?; + + self.sock.send_with_fds(&[IoSlice::new(&bytes)], &fds)?; + + Ok(()) + } +} + +impl<Send, Recv: for<'de> DeserializeWithFds<'de>> Socket<Send, Recv> { + pub fn recv(&self) -> Result<Recv, Error> { + let (bytes, fds) = self.sock.recv_as_vec_with_fds()?; + let mut fds_iter = fds.into_iter(); + + let mut deserializer = Deserializer::from_slice(&bytes, DefaultOptions::new()); + let deserializer_with_fds = DeserializerWithFds::new(&mut fds_iter, &mut deserializer); + + Ok(Recv::deserialize(deserializer_with_fds)?) + } +} |