• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::{
6     io::IoSlice,
7     marker::PhantomData,
8     os::unix::prelude::{AsRawFd, RawFd},
9     time::Duration,
10 };
11 
12 use crate::descriptor::{AsRawDescriptor, FromRawDescriptor, SafeDescriptor};
13 use crate::{
14     platform::{deserialize_with_descriptors, SerializeDescriptors},
15     tube::{Error, RecvTube, Result, SendTube},
16     RawDescriptor, ReadNotifier, ScmSocket, UnixSeqpacket, UnsyncMarker,
17 };
18 
19 use serde::{de::DeserializeOwned, Deserialize, Serialize};
20 
21 /// Bidirectional tube that support both send and recv.
22 #[derive(Serialize, Deserialize)]
23 pub struct Tube {
24     socket: UnixSeqpacket,
25 
26     // Windows is !Sync. We share that characteristic to prevent writing cross-platform incompatible
27     // code.
28     _unsync_marker: UnsyncMarker,
29 }
30 
31 impl Tube {
32     /// Create a pair of connected tubes. Request is sent in one direction while response is in the
33     /// other direction.
pair() -> Result<(Tube, Tube)>34     pub fn pair() -> Result<(Tube, Tube)> {
35         let (socket1, socket2) = UnixSeqpacket::pair().map_err(Error::Pair)?;
36         let tube1 = Tube::new(socket1);
37         let tube2 = Tube::new(socket2);
38         Ok((tube1, tube2))
39     }
40 
41     /// Create a new `Tube`.
new(socket: UnixSeqpacket) -> Tube42     pub fn new(socket: UnixSeqpacket) -> Tube {
43         Tube {
44             socket,
45             _unsync_marker: PhantomData,
46         }
47     }
48 
49     /// DO NOT USE this method directly as it will become private soon (b/221484449). Use a
50     /// directional Tube pair instead.
51     #[deprecated]
try_clone(&self) -> Result<Self>52     pub fn try_clone(&self) -> Result<Self> {
53         self.socket.try_clone().map(Tube::new).map_err(Error::Clone)
54     }
55 
send<T: Serialize>(&self, msg: &T) -> Result<()>56     pub fn send<T: Serialize>(&self, msg: &T) -> Result<()> {
57         let msg_serialize = SerializeDescriptors::new(&msg);
58         let msg_json = serde_json::to_vec(&msg_serialize).map_err(Error::Json)?;
59         let msg_descriptors = msg_serialize.into_descriptors();
60 
61         self.socket
62             .send_with_fds(&[IoSlice::new(&msg_json)], &msg_descriptors)
63             .map_err(Error::Send)?;
64         Ok(())
65     }
66 
recv<T: DeserializeOwned>(&self) -> Result<T>67     pub fn recv<T: DeserializeOwned>(&self) -> Result<T> {
68         let (msg_json, msg_descriptors) =
69             self.socket.recv_as_vec_with_fds().map_err(Error::Recv)?;
70 
71         if msg_json.is_empty() {
72             return Err(Error::Disconnected);
73         }
74 
75         let mut msg_descriptors_safe = msg_descriptors
76             .into_iter()
77             .map(|v| {
78                 Some(unsafe {
79                     // Safe because the socket returns new fds that are owned locally by this scope.
80                     SafeDescriptor::from_raw_descriptor(v)
81                 })
82             })
83             .collect();
84 
85         deserialize_with_descriptors(
86             || serde_json::from_slice(&msg_json),
87             &mut msg_descriptors_safe,
88         )
89         .map_err(Error::Json)
90     }
91 
set_send_timeout(&self, timeout: Option<Duration>) -> Result<()>92     pub fn set_send_timeout(&self, timeout: Option<Duration>) -> Result<()> {
93         self.socket
94             .set_write_timeout(timeout)
95             .map_err(Error::SetSendTimeout)
96     }
97 
set_recv_timeout(&self, timeout: Option<Duration>) -> Result<()>98     pub fn set_recv_timeout(&self, timeout: Option<Duration>) -> Result<()> {
99         self.socket
100             .set_read_timeout(timeout)
101             .map_err(Error::SetRecvTimeout)
102     }
103 }
104 
105 impl AsRawDescriptor for Tube {
as_raw_descriptor(&self) -> RawDescriptor106     fn as_raw_descriptor(&self) -> RawDescriptor {
107         self.socket.as_raw_descriptor()
108     }
109 }
110 
111 impl AsRawFd for Tube {
as_raw_fd(&self) -> RawFd112     fn as_raw_fd(&self) -> RawFd {
113         self.socket.as_raw_fd()
114     }
115 }
116 
117 impl ReadNotifier for Tube {
get_read_notifier(&self) -> &dyn AsRawDescriptor118     fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
119         &self.socket
120     }
121 }
122 
123 impl FromRawDescriptor for Tube {
124     /// # Safety:
125     /// Requirements:
126     /// (1) The caller owns rd.
127     /// (2) When the call completes, ownership of rd has transferred to the returned value.
from_raw_descriptor(rd: RawDescriptor) -> Self128     unsafe fn from_raw_descriptor(rd: RawDescriptor) -> Self {
129         Self {
130             socket: UnixSeqpacket::from_raw_descriptor(rd),
131             _unsync_marker: PhantomData,
132         }
133     }
134 }
135 
136 impl AsRawFd for SendTube {
as_raw_fd(&self) -> RawFd137     fn as_raw_fd(&self) -> RawFd {
138         self.0.as_raw_descriptor()
139     }
140 }
141 
142 impl AsRawFd for RecvTube {
as_raw_fd(&self) -> RawFd143     fn as_raw_fd(&self) -> RawFd {
144         self.0.as_raw_descriptor()
145     }
146 }
147