1 // Copyright 2017 The Fuchsia 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 //! Type-safe bindings for Zircon channel objects.
6 
7 use {AsHandleRef, HandleBased, Handle, HandleRef, Peered, Status, Time, usize_into_u32, size_to_u32_sat};
8 use {sys, ok};
9 use std::mem;
10 
11 /// An object representing a Zircon
12 /// [channel](https://fuchsia.googlesource.com/zircon/+/master/docs/objects/channel.md).
13 ///
14 /// As essentially a subtype of `Handle`, it can be freely interconverted.
15 #[derive(Debug, Eq, PartialEq, Hash)]
16 pub struct Channel(Handle);
17 impl_handle_based!(Channel);
18 impl Peered for Channel {}
19 
20 impl Channel {
21     /// Create a channel, resulting an a pair of `Channel` objects representing both
22     /// sides of the channel. Messages written into one maybe read from the opposite.
23     ///
24     /// Wraps the
25     /// [zx_channel_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/channel_create.md)
26     /// syscall.
create() -> Result<(Channel, Channel), Status>27     pub fn create() -> Result<(Channel, Channel), Status> {
28         unsafe {
29             let mut handle0 = 0;
30             let mut handle1 = 0;
31             let opts = 0;
32             ok(sys::zx_channel_create(opts, &mut handle0, &mut handle1))?;
33             Ok((
34                 Self::from(Handle::from_raw(handle0)),
35                 Self::from(Handle::from_raw(handle1))
36                 ))
37         }
38     }
39 
40     /// Read a message from a channel. Wraps the
41     /// [zx_channel_read](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/channel_read.md)
42     /// syscall.
43     ///
44     /// If the `MessageBuf` lacks the capacity to hold the pending message,
45     /// returns an `Err` with the number of bytes and number of handles needed.
46     /// Otherwise returns an `Ok` with the result as usual.
read_raw(&self, buf: &mut MessageBuf) -> Result<Result<(), Status>, (usize, usize)>47     pub fn read_raw(&self, buf: &mut MessageBuf)
48         -> Result<Result<(), Status>, (usize, usize)>
49     {
50         let opts = 0;
51         unsafe {
52             buf.clear();
53             let raw_handle = self.raw_handle();
54             let mut num_bytes: u32 = size_to_u32_sat(buf.bytes.capacity());
55             let mut num_handles: u32 = size_to_u32_sat(buf.handles.capacity());
56             let status = ok(sys::zx_channel_read(raw_handle, opts,
57                 buf.bytes.as_mut_ptr(), buf.handles.as_mut_ptr() as *mut _,
58                 num_bytes, num_handles, &mut num_bytes, &mut num_handles));
59             if status == Err(Status::BUFFER_TOO_SMALL) {
60                 Err((num_bytes as usize, num_handles as usize))
61             } else {
62                 Ok(status.map(|()| {
63                     buf.bytes.set_len(num_bytes as usize);
64                     buf.handles.set_len(num_handles as usize);
65                 }))
66             }
67         }
68     }
69 
70     /// Read a message from a channel.
71     ///
72     /// Note that this method can cause internal reallocations in the `MessageBuf`
73     /// if it is lacks capacity to hold the full message. If such reallocations
74     /// are not desirable, use `read_raw` instead.
read(&self, buf: &mut MessageBuf) -> Result<(), Status>75     pub fn read(&self, buf: &mut MessageBuf) -> Result<(), Status> {
76         loop {
77             match self.read_raw(buf) {
78                 Ok(result) => return result,
79                 Err((num_bytes, num_handles)) => {
80                     buf.ensure_capacity_bytes(num_bytes);
81                     buf.ensure_capacity_handles(num_handles);
82                 }
83             }
84         }
85     }
86 
87     /// Write a message to a channel. Wraps the
88     /// [zx_channel_write](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/channel_write.md)
89     /// syscall.
write(&self, bytes: &[u8], handles: &mut Vec<Handle>) -> Result<(), Status>90     pub fn write(&self, bytes: &[u8], handles: &mut Vec<Handle>)
91             -> Result<(), Status>
92     {
93         let opts = 0;
94         let n_bytes = try!(usize_into_u32(bytes.len()).map_err(|_| Status::OUT_OF_RANGE));
95         let n_handles = try!(usize_into_u32(handles.len()).map_err(|_| Status::OUT_OF_RANGE));
96         unsafe {
97             let status = sys::zx_channel_write(self.raw_handle(), opts, bytes.as_ptr(), n_bytes,
98                 handles.as_ptr() as *const sys::zx_handle_t, n_handles);
99             ok(status)?;
100             // Handles were successfully transferred, forget them on sender side
101             handles.set_len(0);
102             Ok(())
103         }
104     }
105 
106     /// Send a message consisting of the given bytes and handles to a channel and await a reply. The
107     /// bytes should start with a four byte 'txid' which is used to identify the matching reply.
108     ///
109     /// Wraps the
110     /// [zx_channel_call](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/channel_call.md)
111     /// syscall.
112     ///
113     /// Note that unlike [`read`][read], the caller must ensure that the MessageBuf has enough
114     /// capacity for the bytes and handles which will be received, as replies which are too large
115     /// are discarded.
116     ///
117     /// On failure returns the both the main and read status.
118     ///
119     /// [read]: struct.Channel.html#method.read
call(&self, timeout: Time, bytes: &[u8], handles: &mut Vec<Handle>, buf: &mut MessageBuf) -> Result<(), (Status, Status)>120     pub fn call(&self, timeout: Time, bytes: &[u8], handles: &mut Vec<Handle>,
121         buf: &mut MessageBuf) -> Result<(), (Status, Status)>
122     {
123         let write_num_bytes = try!(usize_into_u32(bytes.len()).map_err(
124             |_| (Status::OUT_OF_RANGE, Status::OK)));
125         let write_num_handles = try!(usize_into_u32(handles.len()).map_err(
126             |_| (Status::OUT_OF_RANGE, Status::OK)));
127         buf.clear();
128         let read_num_bytes: u32 = size_to_u32_sat(buf.bytes.capacity());
129         let read_num_handles: u32 = size_to_u32_sat(buf.handles.capacity());
130         let args = sys::zx_channel_call_args_t {
131             wr_bytes: bytes.as_ptr(),
132             wr_handles: handles.as_ptr() as *const sys::zx_handle_t,
133             rd_bytes: buf.bytes.as_mut_ptr(),
134             rd_handles: buf.handles.as_mut_ptr() as *mut _,
135             wr_num_bytes: write_num_bytes,
136             wr_num_handles: write_num_handles,
137             rd_num_bytes: read_num_bytes,
138             rd_num_handles: read_num_handles,
139         };
140         let mut actual_read_bytes: u32 = 0;
141         let mut actual_read_handles: u32 = 0;
142         let mut read_status = Status::OK.into_raw();
143         let options = 0;
144         let status = unsafe {
145             Status::from_raw(
146                 sys::zx_channel_call(
147                     self.raw_handle(), options, timeout.nanos(), &args, &mut actual_read_bytes,
148                     &mut actual_read_handles, &mut read_status))
149         };
150 
151         match status {
152             Status::OK |
153             Status::TIMED_OUT |
154             Status::CALL_FAILED => {
155                 // Handles were successfully transferred,
156                 // even if we didn't get a response, so forget
157                 // them on the sender side.
158                 unsafe { handles.set_len(0); }
159             }
160             _ => {}
161         }
162 
163         unsafe {
164             buf.bytes.set_len(actual_read_bytes as usize);
165             buf.handles.set_len(actual_read_handles as usize);
166         }
167         if Status::OK == status {
168             Ok(())
169         } else {
170             Err((status, Status::from_raw(read_status)))
171         }
172     }
173 }
174 
175 #[test]
test_handle_repr()176 pub fn test_handle_repr() {
177     assert_eq!(::std::mem::size_of::<sys::zx_handle_t>(), 4);
178     assert_eq!(::std::mem::size_of::<Handle>(), 4);
179     assert_eq!(::std::mem::align_of::<sys::zx_handle_t>(), ::std::mem::align_of::<Handle>());
180 
181     // This test asserts that repr(transparent) still works for Handle -> zx_handle_t
182 
183     let n: Vec<sys::zx_handle_t> = vec![0, 100, 2<<32-1];
184     let v: Vec<Handle> = n.iter().map(|h| unsafe { Handle::from_raw(*h) } ).collect();
185 
186     for (handle, raw) in v.iter().zip(n.iter()) {
187         unsafe {
188             assert_eq!(*(handle as *const _ as *const [u8; 4]), *(raw as *const _ as *const [u8; 4]));
189         }
190     }
191 
192     for h in v.into_iter() {
193         ::std::mem::forget(h);
194     }
195 }
196 
197 impl AsRef<Channel> for Channel {
as_ref(&self) -> &Self198     fn as_ref(&self) -> &Self {
199         &self
200     }
201 }
202 
203 /// A buffer for _receiving_ messages from a channel.
204 ///
205 /// A `MessageBuf` is essentially a byte buffer and a vector of
206 /// handles, but move semantics for "taking" handles requires special handling.
207 ///
208 /// Note that for sending messages to a channel, the caller manages the buffers,
209 /// using a plain byte slice and `Vec<Handle>`.
210 #[derive(Default)]
211 #[derive(Debug)]
212 pub struct MessageBuf {
213     bytes: Vec<u8>,
214     handles: Vec<Handle>,
215 }
216 
217 impl MessageBuf {
218     /// Create a new, empty, message buffer.
new() -> Self219     pub fn new() -> Self {
220         Default::default()
221     }
222 
223     /// Create a new non-empty message buffer.
new_with(v: Vec<u8>, h: Vec<Handle>) -> Self224     pub fn new_with(v: Vec<u8>, h: Vec<Handle>) -> Self {
225         Self{
226             bytes: v,
227             handles: h,
228         }
229     }
230 
231     /// Ensure that the buffer has the capacity to hold at least `n_bytes` bytes.
ensure_capacity_bytes(&mut self, n_bytes: usize)232     pub fn ensure_capacity_bytes(&mut self, n_bytes: usize) {
233         ensure_capacity(&mut self.bytes, n_bytes);
234     }
235 
236     /// Ensure that the buffer has the capacity to hold at least `n_handles` handles.
ensure_capacity_handles(&mut self, n_handles: usize)237     pub fn ensure_capacity_handles(&mut self, n_handles: usize) {
238         ensure_capacity(&mut self.handles, n_handles);
239     }
240 
241     /// Ensure that at least n_bytes bytes are initialized (0 fill).
ensure_initialized_bytes(&mut self, n_bytes: usize)242     pub fn ensure_initialized_bytes(&mut self, n_bytes: usize) {
243         if n_bytes <= self.bytes.len() {
244             return;
245         }
246         self.bytes.resize(n_bytes, 0);
247     }
248 
249     /// Get a reference to the bytes of the message buffer, as a `&[u8]` slice.
bytes(&self) -> &[u8]250     pub fn bytes(&self) -> &[u8] {
251         self.bytes.as_slice()
252     }
253 
254     /// The number of handles in the message buffer. Note this counts the number
255     /// available when the message was received; `take_handle` does not affect
256     /// the count.
n_handles(&self) -> usize257     pub fn n_handles(&self) -> usize {
258         self.handles.len()
259     }
260 
261     /// Take the handle at the specified index from the message buffer. If the
262     /// method is called again with the same index, it will return `None`, as
263     /// will happen if the index exceeds the number of handles available.
take_handle(&mut self, index: usize) -> Option<Handle>264     pub fn take_handle(&mut self, index: usize) -> Option<Handle> {
265         self.handles.get_mut(index).and_then(|handle|
266             if handle.is_invalid() {
267                 None
268             } else {
269                 Some(mem::replace(handle, Handle::invalid()))
270             }
271         )
272     }
273 
274     /// Clear the bytes and handles contained in the buf. This will drop any
275     /// contained handles, resulting in their resources being freed.
clear(&mut self)276     pub fn clear(&mut self) {
277         self.bytes.clear();
278         self.handles.clear();
279     }
280 }
281 
ensure_capacity<T>(vec: &mut Vec<T>, size: usize)282 fn ensure_capacity<T>(vec: &mut Vec<T>, size: usize) {
283     let len = vec.len();
284     if size > len {
285         vec.reserve(size - len);
286     }
287 }
288 
289 #[cfg(test)]
290 mod tests {
291     use super::*;
292     use {DurationNum, Rights, Signals, Vmo};
293     use std::thread;
294 
295     #[test]
channel_basic()296     fn channel_basic() {
297         let (p1, p2) = Channel::create().unwrap();
298 
299         let mut empty = vec![];
300         assert!(p1.write(b"hello", &mut empty).is_ok());
301 
302         let mut buf = MessageBuf::new();
303         assert!(p2.read(&mut buf).is_ok());
304         assert_eq!(buf.bytes(), b"hello");
305     }
306 
307     #[test]
channel_read_raw_too_small()308     fn channel_read_raw_too_small() {
309         let (p1, p2) = Channel::create().unwrap();
310 
311         let mut empty = vec![];
312         assert!(p1.write(b"hello", &mut empty).is_ok());
313 
314         let mut buf = MessageBuf::new();
315         let result = p2.read_raw(&mut buf);
316         assert_eq!(result, Err((5, 0)));
317         assert_eq!(buf.bytes(), b"");
318     }
319 
320     #[test]
channel_send_handle()321     fn channel_send_handle() {
322         let hello_length: usize = 5;
323 
324         // Create a pair of channels and a virtual memory object.
325         let (p1, p2) = Channel::create().unwrap();
326         let vmo = Vmo::create(hello_length as u64).unwrap();
327 
328         // Duplicate VMO handle and send it down the channel.
329         let duplicate_vmo_handle = vmo.duplicate_handle(Rights::SAME_RIGHTS).unwrap().into();
330         let mut handles_to_send: Vec<Handle> = vec![duplicate_vmo_handle];
331         assert!(p1.write(b"", &mut handles_to_send).is_ok());
332         // Handle should be removed from vector.
333         assert!(handles_to_send.is_empty());
334 
335         // Read the handle from the receiving channel.
336         let mut buf = MessageBuf::new();
337         assert!(p2.read(&mut buf).is_ok());
338         assert_eq!(buf.n_handles(), 1);
339         // Take the handle from the buffer.
340         let received_handle = buf.take_handle(0).unwrap();
341         // Should not affect number of handles.
342         assert_eq!(buf.n_handles(), 1);
343         // Trying to take it again should fail.
344         assert!(buf.take_handle(0).is_none());
345 
346         // Now to test that we got the right handle, try writing something to it...
347         let received_vmo = Vmo::from(received_handle);
348         assert_eq!(received_vmo.write(b"hello", 0).unwrap(), hello_length);
349 
350         // ... and reading it back from the original VMO.
351         let mut read_vec = vec![0; hello_length];
352         assert_eq!(vmo.read(&mut read_vec, 0).unwrap(), hello_length);
353         assert_eq!(read_vec, b"hello");
354     }
355 
356     #[test]
channel_call_timeout()357     fn channel_call_timeout() {
358         let ten_ms = 10.millis();
359 
360         // Create a pair of channels and a virtual memory object.
361         let (p1, p2) = Channel::create().unwrap();
362         let vmo = Vmo::create(0 as u64).unwrap();
363 
364         // Duplicate VMO handle and send it along with the call.
365         let duplicate_vmo_handle = vmo.duplicate_handle(Rights::SAME_RIGHTS).unwrap().into();
366         let mut handles_to_send: Vec<Handle> = vec![duplicate_vmo_handle];
367         let mut buf = MessageBuf::new();
368         assert_eq!(p1.call(ten_ms.after_now(), b"call", &mut handles_to_send, &mut buf),
369             Err((Status::TIMED_OUT, Status::OK)));
370         // Handle should be removed from vector even though we didn't get a response, as it was
371         // still sent over the channel.
372         assert!(handles_to_send.is_empty());
373 
374         // Should be able to read call even though it timed out waiting for a response.
375         let mut buf = MessageBuf::new();
376         assert!(p2.read(&mut buf).is_ok());
377         assert_eq!(buf.bytes(), b"call");
378         assert_eq!(buf.n_handles(), 1);
379     }
380 
381     #[test]
channel_call()382     fn channel_call() {
383         // Create a pair of channels
384         let (p1, p2) = Channel::create().unwrap();
385 
386         // create an mpsc channel for communicating the call data for later assertion
387         let (tx, rx) = ::std::sync::mpsc::channel();
388 
389         // Start a new thread to respond to the call.
390         thread::spawn(move || {
391             let mut buf = MessageBuf::new();
392             // if either the read or the write fail, this thread will panic,
393             // resulting in tx being dropped, which will be noticed by the rx.
394             p2.wait_handle(Signals::CHANNEL_READABLE, 1.seconds().after_now()).expect("callee wait error");
395             p2.read(&mut buf).expect("callee read error");
396             p2.write(b"txidresponse", &mut vec![]).expect("callee write error");
397             tx.send(buf).expect("callee mpsc send error");
398         });
399 
400         // Make the call.
401         let mut buf = MessageBuf::new();
402         buf.ensure_capacity_bytes(12);
403         // NOTE(raggi): CQ has been seeing some long stalls from channel call,
404         // and it's as yet unclear why. The timeout here has been made much
405         // larger in order to avoid that, as the issues are not issues with this
406         // crate's concerns. The timeout is here just to prevent the tests from
407         // stalling forever if a developer makes a mistake locally in this
408         // crate. Tests of Zircon behavior or virtualization behavior should be
409         // covered elsewhere. See ZX-1324.
410         p1.call(30.seconds().after_now(), b"txidcall", &mut vec![], &mut buf).expect("channel call error");
411         assert_eq!(buf.bytes(), b"txidresponse");
412         assert_eq!(buf.n_handles(), 0);
413 
414         let sbuf = rx.recv().expect("mpsc channel recv error");
415         assert_eq!(sbuf.bytes(), b"txidcall");
416         assert_eq!(sbuf.n_handles(), 0);
417     }
418 }
419