1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 use alloc::rc::{Rc, Weak}; 18 use core::fmt; 19 use core::mem::{ManuallyDrop, MaybeUninit}; 20 use core::num::ParseIntError; 21 use log::{debug, error, warn}; 22 use trusty_std::alloc::{AllocError, Vec}; 23 use trusty_std::ffi::{CString, FallibleCString}; 24 use trusty_std::TryClone; 25 use trusty_sys::c_void; 26 27 use crate::handle::MAX_MSG_HANDLES; 28 use crate::sys; 29 use crate::{ConnectResult, Deserialize, Handle, MessageResult, Result, TipcError}; 30 use handle_set::HandleSet; 31 32 mod handle_set; 33 34 /// A description of a server-side IPC port. 35 /// 36 /// A port configuration specifies the service port and various parameters for 37 /// the service. This configuration struct is a builder to set these parameters. 38 /// 39 /// # Examples 40 /// 41 /// ``` 42 /// # impl Service for () { 43 /// # type Connection = (); 44 /// # type Message = (); 45 /// 46 /// # fn on_connect( 47 /// # &self, 48 /// # _port: &PortCfg, 49 /// # _handle: &Handle, 50 /// # _peer: &Uuid, 51 /// # ) -> Result<ConnectResult<Self::Connection>> { 52 /// # Ok(ConnectResult::Accept(())) 53 /// # } 54 /// # 55 /// # fn on_message( 56 /// # &self, 57 /// # _connection: &Self::Connection, 58 /// # _handle: &Handle, 59 /// # _msg: Self::Message, 60 /// # ) -> Result<MessageResult> { 61 /// # Ok(MessageResult::MaintainConnection) 62 /// # } 63 /// # } 64 /// 65 /// let cfg = PortCfg::new("com.android.trusty.rust_port_test") 66 /// .msg_queue_len(4) 67 /// .msg_max_size(4096) 68 /// .allow_ta_connect(); 69 /// 70 /// let service = (); 71 /// let buffer = [0u8; 4096]; 72 /// let manager = Manager::new(service, cfg, buffer); 73 /// ``` 74 #[derive(Debug, Eq, PartialEq)] 75 pub struct PortCfg { 76 path: CString, 77 msg_queue_len: u32, 78 msg_max_size: u32, 79 flags: u32, 80 } 81 82 impl PortCfg { 83 /// Construct a new port configuration for the given path new<T: AsRef<str>>(path: T) -> Result<Self>84 pub fn new<T: AsRef<str>>(path: T) -> Result<Self> { 85 Ok(Self { 86 path: CString::try_new(path.as_ref())?, 87 msg_queue_len: 1, 88 msg_max_size: 4096, 89 flags: 0, 90 }) 91 } 92 93 /// Construct a new port configuration for the given path 94 /// 95 /// This version takes ownership of the path and does not allocate. new_raw(path: CString) -> Self96 pub fn new_raw(path: CString) -> Self { 97 Self { path, msg_queue_len: 1, msg_max_size: 4096, flags: 0 } 98 } 99 100 /// Set the message queue length for this port configuration msg_queue_len(self, msg_queue_len: u32) -> Self101 pub fn msg_queue_len(self, msg_queue_len: u32) -> Self { 102 Self { msg_queue_len, ..self } 103 } 104 105 /// Set the message maximum length for this port configuration msg_max_size(self, msg_max_size: u32) -> Self106 pub fn msg_max_size(self, msg_max_size: u32) -> Self { 107 Self { msg_max_size, ..self } 108 } 109 110 /// Allow connections from non-secure (Android) clients for this port 111 /// configuration allow_ns_connect(self) -> Self112 pub fn allow_ns_connect(self) -> Self { 113 Self { flags: self.flags | sys::IPC_PORT_ALLOW_NS_CONNECT as u32, ..self } 114 } 115 116 /// Allow connections from secure (Trusty) client for this port 117 /// configuration allow_ta_connect(self) -> Self118 pub fn allow_ta_connect(self) -> Self { 119 Self { flags: self.flags | sys::IPC_PORT_ALLOW_TA_CONNECT as u32, ..self } 120 } 121 } 122 123 impl TryClone for PortCfg { 124 type Error = AllocError; 125 try_clone(&self) -> core::result::Result<Self, Self::Error>126 fn try_clone(&self) -> core::result::Result<Self, Self::Error> { 127 Ok(Self { path: self.path.try_clone()?, ..*self }) 128 } 129 } 130 131 pub(crate) struct Channel<D: Dispatcher> { 132 handle: Handle, 133 ty: ChannelTy<D>, 134 } 135 136 impl<D: Dispatcher> PartialEq for Channel<D> { eq(&self, other: &Self) -> bool137 fn eq(&self, other: &Self) -> bool { 138 self.handle == other.handle 139 } 140 } 141 142 impl<D: Dispatcher> Eq for Channel<D> {} 143 144 impl<D: Dispatcher> fmt::Debug for Channel<D> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 146 writeln!(f, "Channel {{")?; 147 writeln!(f, " handle: {:?},", self.handle)?; 148 writeln!(f, " ty: {:?},", self.ty)?; 149 write!(f, "}}") 150 } 151 } 152 153 enum ChannelTy<D: Dispatcher> { 154 /// Service port with a configuration describing the port 155 Port(PortCfg), 156 157 /// Client connection 158 Connection(D::Connection), 159 } 160 161 impl<D: Dispatcher> fmt::Debug for ChannelTy<D> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 163 match self { 164 ChannelTy::Port(cfg) => write!(f, "ChannelTy::Port({:?})", cfg), 165 ChannelTy::Connection(_) => write!(f, "ChannelTy::Connection"), 166 } 167 } 168 } 169 170 impl<D: Dispatcher> Channel<D> { handle(&self) -> &Handle171 pub fn handle(&self) -> &Handle { 172 &self.handle 173 } 174 is_port(&self) -> bool175 pub fn is_port(&self) -> bool { 176 match self.ty { 177 ChannelTy::Port(..) => true, 178 _ => false, 179 } 180 } 181 is_connection(&self) -> bool182 pub fn is_connection(&self) -> bool { 183 match self.ty { 184 ChannelTy::Connection(..) => true, 185 _ => false, 186 } 187 } 188 189 /// Reconstruct a reference to this type from an opaque pointer. 190 /// 191 /// SAFETY: The opaque pointer must have been constructed using 192 /// Weak::into_raw, which happens in HandleSet::do_set_ctrl to create a 193 /// connection cookie. from_opaque_ptr<'a>(ptr: *const c_void) -> Option<Rc<Self>>194 unsafe fn from_opaque_ptr<'a>(ptr: *const c_void) -> Option<Rc<Self>> { 195 if ptr.is_null() { 196 None 197 } else { 198 // We must not drop the weak pointer here, because we are not 199 // actually taking ownership of it. 200 let weak = ManuallyDrop::new(Weak::from_raw(ptr.cast())); 201 weak.upgrade() 202 } 203 } 204 try_new_port(cfg: &PortCfg) -> Result<Rc<Self>>205 pub(crate) fn try_new_port(cfg: &PortCfg) -> Result<Rc<Self>> { 206 // SAFETY: syscall, config path is borrowed and outlives the call. 207 // Return value is either a negative error code or a valid handle. 208 let rc = unsafe { 209 trusty_sys::port_create( 210 cfg.path.as_ptr(), 211 cfg.msg_queue_len, 212 cfg.msg_max_size, 213 cfg.flags, 214 ) 215 }; 216 if rc < 0 { 217 Err(TipcError::from_uapi(rc)) 218 } else { 219 Ok(Rc::try_new(Self { 220 handle: Handle::from_raw(rc as i32)?, 221 ty: ChannelTy::Port(cfg.try_clone()?), 222 })?) 223 } 224 } 225 try_new_connection(handle: Handle, data: D::Connection) -> Result<Rc<Self>>226 fn try_new_connection(handle: Handle, data: D::Connection) -> Result<Rc<Self>> { 227 Ok(Rc::try_new(Self { handle, ty: ChannelTy::Connection(data) })?) 228 } 229 } 230 231 /// Trusty APP UUID 232 #[derive(Clone, Eq, PartialEq)] 233 pub struct Uuid(trusty_sys::uuid); 234 235 impl Uuid { 236 const UUID_BYTE_LEN: usize = std::mem::size_of::<trusty_sys::uuid>(); 237 // UUID_STR_SIZE is a u32, conversion to usize is correct on our targeted architectures 238 // Subtracting 1 from UUID_STR_SIZE because we don't need the null terminator on the RUST 239 // implementation. 240 const UUID_STR_LEN: usize = (sys::UUID_STR_SIZE as usize) - 1; 241 const HYPHEN_SKIP_POS: [usize; 4] = [8, 4, 4, 4]; 242 const CLOCK_SEQ_AND_NODE_NUM_BYTES: usize = 8; 243 new( time_low: u32, time_mid: u16, time_hi_and_version: u16, clock_seq_and_node: [u8; 8], ) -> Self244 pub const fn new( 245 time_low: u32, 246 time_mid: u16, 247 time_hi_and_version: u16, 248 clock_seq_and_node: [u8; 8], 249 ) -> Self { 250 Uuid(trusty_sys::uuid { time_low, time_mid, time_hi_and_version, clock_seq_and_node }) 251 } 252 from_bytes(bytes: &[u8; Self::UUID_BYTE_LEN]) -> Self253 pub fn from_bytes(bytes: &[u8; Self::UUID_BYTE_LEN]) -> Self { 254 // SAFETY: `bytes` has the exact same size size as `trusty_sys::uuid`, so this transmute 255 // copy is safe. 256 let uuid = unsafe { std::mem::transmute_copy(bytes) }; 257 Uuid(uuid) 258 } 259 try_from_bytes(bytes: &[u8]) -> Result<Self>260 pub fn try_from_bytes(bytes: &[u8]) -> Result<Self> { 261 let bytes: &[u8; Self::UUID_BYTE_LEN] = bytes.try_into().or(Err(TipcError::OutOfBounds))?; 262 Ok(Self::from_bytes(bytes)) 263 } 264 as_ptr(&self) -> *const trusty_sys::uuid265 pub unsafe fn as_ptr(&self) -> *const trusty_sys::uuid { 266 &self.0 267 } 268 new_from_string(uuid_str: &str) -> Result<Self>269 pub fn new_from_string(uuid_str: &str) -> Result<Self> { 270 // Helper function that first tries to convert the `uuid_element` bytes into a string and 271 // then uses the provided `conversion_fn` to try to convert it into an integer, interpreting 272 // the string as a hex number 273 fn convert_uuid_element<T>( 274 uuid_element: Option<&str>, 275 conversion_fn: fn(&str, u32) -> core::result::Result<T, ParseIntError>, 276 ) -> Result<T> { 277 let uuid_element = uuid_element.ok_or(TipcError::InvalidData)?; 278 conversion_fn(uuid_element, 16).map_err(|_| TipcError::InvalidData) 279 } 280 // Splitting a string into chunks using only std Rust facilities is not stable yet, so 281 // providing a function for `Uuid` usage until it is stabilized. 282 fn split_convert_string_byte_chunks( 283 string_to_split: &str, 284 result_buffer: &mut [u8], 285 ) -> Result<()> { 286 // Because our input is in hexadecimal format, to get a byte we need a string of size 2. 287 let chunk_size = 2; 288 if (string_to_split.len() % chunk_size) != 0 { 289 return Err(TipcError::InvalidData); 290 } 291 let mut chunk; 292 let mut remainder = string_to_split; 293 for i in 0..(string_to_split.len() / chunk_size) { 294 (chunk, remainder) = remainder.split_at(chunk_size); 295 let converted_byte = convert_uuid_element(Some(chunk), u8::from_str_radix)?; 296 result_buffer[i] = converted_byte; 297 } 298 Ok(()) 299 } 300 // checking first that provided string is ASCII, so we can later split clock_seq_and_node in 301 // byte chunks. 302 if !uuid_str.is_ascii() { 303 return Err(TipcError::InvalidData); 304 } 305 // Check that string has the correct length 306 if uuid_str.len() != Self::UUID_STR_LEN { 307 return Err(TipcError::InvalidData); 308 } 309 // Check that hyphens are in the correct positions. 310 let mut uuid_chr_itr = uuid_str.chars(); 311 for skip_pos in Self::HYPHEN_SKIP_POS { 312 if uuid_chr_itr.nth(skip_pos) != Some('-') { 313 return Err(TipcError::InvalidData); 314 } 315 } 316 // Splitting by the hyphens and checking that we do not end up with more elements than 317 // expected. This checks that we didn't have some unexpected hyphens in the middle of the 318 // string. This, along with the previous 2 checks should also check that all the elements 319 // have the correct number of digits. 320 let uuid_elements = uuid_str.split(|c| c == '-'); 321 if uuid_elements.count() != 5 { 322 return Err(TipcError::InvalidData); 323 } 324 // separating uuid at the '-' now that we know that the string is of the correct length and 325 // has the expected number of hyphens. 326 let mut uuid_elements = uuid_str.split(|c| c == '-'); 327 let time_low = convert_uuid_element(uuid_elements.next(), u32::from_str_radix)?; 328 let time_mid = convert_uuid_element(uuid_elements.next(), u16::from_str_radix)?; 329 let time_hi_and_version = convert_uuid_element(uuid_elements.next(), u16::from_str_radix)?; 330 // The last 8 bytes are split in 2 elements. RFC 4122 states that it is stored in Big Endian 331 // format, so we are just going to concatenate the individual byte chunks of the 2 elements. 332 let mut clock_seq_and_node = [0u8; Self::CLOCK_SEQ_AND_NODE_NUM_BYTES]; 333 let clock_seq = uuid_elements.next().ok_or(TipcError::InvalidData)?; 334 // clock_seq contains the first 2 bytes 335 split_convert_string_byte_chunks(clock_seq, &mut clock_seq_and_node[..2])?; 336 let node = uuid_elements.next().ok_or(TipcError::InvalidData)?; 337 // node contains the remaining 6 bytes 338 split_convert_string_byte_chunks(node, &mut clock_seq_and_node[2..])?; 339 Ok(Self::new(time_low, time_mid, time_hi_and_version, clock_seq_and_node)) 340 } 341 } 342 343 impl fmt::Debug for Uuid { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result344 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 345 write!( 346 f, 347 "{:08x}-{:04x}-{:04x}-", 348 self.0.time_low, self.0.time_mid, self.0.time_hi_and_version 349 )?; 350 for (idx, b) in self.0.clock_seq_and_node.iter().enumerate() { 351 write!(f, "{:02x}", b)?; 352 if idx == 1 { 353 write!(f, "-")?; 354 } 355 } 356 Ok(()) 357 } 358 } 359 360 impl alloc::string::ToString for Uuid { to_string(&self) -> String361 fn to_string(&self) -> String { 362 format!("{:?}", self) 363 } 364 } 365 366 /// A service which handles IPC messages for a collection of ports. 367 /// 368 /// A service which implements this interface can register itself, along with a 369 /// set of ports it handles, with a [`Manager`] which then dispatches 370 /// connection and message events to this service. 371 pub trait Service { 372 /// Generic type to association with a connection. `on_connect()` should 373 /// create this type for a successful connection. 374 type Connection; 375 376 /// Type of message this service can receive. 377 type Message: Deserialize; 378 379 /// Called when a client connects 380 /// 381 /// Returns either `Ok(Accept(Connection))` if the connection should be 382 /// accepted or `Ok(CloseConnection)` if the connection should be closed. on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>383 fn on_connect( 384 &self, 385 port: &PortCfg, 386 handle: &Handle, 387 peer: &Uuid, 388 ) -> Result<ConnectResult<Self::Connection>>; 389 390 /// Called when the service receives a message. 391 /// 392 /// The service manager handles deserializing the message, which is then 393 /// passed to this callback. 394 /// 395 /// Should return `Ok(MaintainConnection)` if the connection should be kept open. The 396 /// connection will be closed if `Ok(CloseConnection)` or `Err(_)` is returned. on_message( &self, connection: &Self::Connection, handle: &Handle, msg: Self::Message, ) -> Result<MessageResult>397 fn on_message( 398 &self, 399 connection: &Self::Connection, 400 handle: &Handle, 401 msg: Self::Message, 402 ) -> Result<MessageResult>; 403 404 /// Called when the client closes a connection. on_disconnect(&self, _connection: &Self::Connection)405 fn on_disconnect(&self, _connection: &Self::Connection) {} 406 } 407 408 pub trait UnbufferedService { 409 /// Generic type to association with a connection. `on_connect()` should 410 /// create this type for a successful connection. 411 type Connection; 412 413 /// Called when a client connects 414 /// 415 /// Returns either `Ok(Accept(Connection))` if the connection should be 416 /// accepted or `Ok(CloseConnection)` if the connection should be closed. on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>417 fn on_connect( 418 &self, 419 port: &PortCfg, 420 handle: &Handle, 421 peer: &Uuid, 422 ) -> Result<ConnectResult<Self::Connection>>; 423 424 /// Called when the service receives a message. 425 /// 426 /// The service is responsible for deserializing the message. 427 /// A default implementation is provided that panics, for reasons of backwards 428 /// compatibility with existing code. Any unbuffered service should implement this 429 /// method and also provide a simple implementation for `on_message` that e.g. logs 430 /// or panics. 431 /// 432 /// Should return `Ok(MaintainConnection)` if the connection should be kept open. The 433 /// connection will be closed if `Ok(CloseConnection)` or `Err(_)` is returned. on_message( &self, connection: &Self::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>434 fn on_message( 435 &self, 436 connection: &Self::Connection, 437 handle: &Handle, 438 buffer: &mut [u8], 439 ) -> Result<MessageResult>; 440 441 /// Called when the client closes a connection. on_disconnect(&self, _connection: &Self::Connection)442 fn on_disconnect(&self, _connection: &Self::Connection) {} 443 444 /// Get the maximum possible length of any message handled by this service max_message_length(&self) -> usize445 fn max_message_length(&self) -> usize { 446 0 447 } 448 } 449 450 impl<T, U: Deserialize, V: Service<Connection = T, Message = U>> UnbufferedService for V { 451 type Connection = <Self as Service>::Connection; 452 on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<<Self as UnbufferedService>::Connection>>453 fn on_connect( 454 &self, 455 port: &PortCfg, 456 handle: &Handle, 457 peer: &Uuid, 458 ) -> Result<ConnectResult<<Self as UnbufferedService>::Connection>> { 459 <Self as Service>::on_connect(self, port, handle, peer) 460 } 461 on_message( &self, connection: &<Self as UnbufferedService>::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>462 fn on_message( 463 &self, 464 connection: &<Self as UnbufferedService>::Connection, 465 handle: &Handle, 466 buffer: &mut [u8], 467 ) -> Result<MessageResult> { 468 let mut handles: [Option<Handle>; MAX_MSG_HANDLES] = Default::default(); 469 let (byte_count, handle_count) = handle.recv_vectored(&mut [buffer], &mut handles)?; 470 let msg = <Self as Service>::Message::deserialize( 471 &buffer[..byte_count], 472 &mut handles[..handle_count], 473 ) 474 .map_err(|e| { 475 error!("Could not parse message: {:?}", e); 476 TipcError::InvalidData 477 })?; 478 <Self as Service>::on_message(self, connection, handle, msg) 479 } 480 on_disconnect(&self, connection: &<Self as UnbufferedService>::Connection)481 fn on_disconnect(&self, connection: &<Self as UnbufferedService>::Connection) { 482 <Self as Service>::on_disconnect(self, connection) 483 } 484 max_message_length(&self) -> usize485 fn max_message_length(&self) -> usize { 486 <Self as Service>::Message::MAX_SERIALIZED_SIZE 487 } 488 } 489 490 /// Wrap a service in a newtype. 491 /// 492 /// This macro wraps an existing service in a newtype 493 /// that forwards the service trait implementation 494 /// (either [`Service`] or [`UnbufferedService`]) to 495 /// the wrapped service. This is useful when passing the 496 /// same service multiple times to the [`service_dispatcher!`] 497 /// macro, which requires that all the service types are distinct. 498 /// The wrapper(s) can be used to serve multiple ports using 499 /// the same service implementation. 500 /// 501 /// [`service_dispatcher!`]: crate::service_dispatcher 502 /// 503 /// # Examples 504 /// 505 /// ``` 506 /// // Create a new Service2 type that wraps Service1 507 /// wrap_service!(Service2(Service1: Service)); 508 /// service_dispatcher! { 509 /// enum ServiceDispatcher { 510 /// Service1, 511 /// Service2, 512 /// } 513 /// } 514 /// ``` 515 #[macro_export] 516 macro_rules! wrap_service { 517 ($vis:vis $wrapper:ident ($inner:ty: Service)) => { 518 $crate::wrap_service!(@common $vis $wrapper $inner); 519 $crate::wrap_service!(@buffered $wrapper $inner); 520 }; 521 522 ($vis:vis $wrapper:ident ($inner:ty: UnbufferedService)) => { 523 $crate::wrap_service!(@common $vis $wrapper $inner); 524 $crate::wrap_service!(@unbuffered $wrapper $inner); 525 }; 526 527 (@common $vis:vis $wrapper:ident $inner:ty) => { 528 $vis struct $wrapper($inner); 529 530 #[allow(dead_code)] // These might not be used by anything 531 impl $wrapper { 532 $vis fn new(inner: $inner) -> Self { Self(inner) } 533 $vis fn inner(&self) -> &$inner { &self.0 } 534 $vis fn inner_mut(&mut self) -> &mut $inner { &mut self.0 } 535 } 536 }; 537 538 (@buffered $wrapper:ident $inner:ty) => { 539 impl $crate::Service for $wrapper { 540 type Connection = <$inner as $crate::Service>::Connection; 541 type Message = <$inner as $crate::Service>::Message; 542 543 fn on_connect( 544 &self, 545 port: &$crate::PortCfg, 546 handle: &$crate::Handle, 547 peer: &$crate::Uuid, 548 ) -> $crate::Result<$crate::ConnectResult<Self::Connection>> { 549 <$inner as $crate::Service>::on_connect(&self.0, port, handle, peer) 550 } 551 552 fn on_message( 553 &self, 554 connection: &Self::Connection, 555 handle: &$crate::Handle, 556 msg: Self::Message, 557 ) -> $crate::Result<$crate::MessageResult> { 558 <$inner as $crate::Service>::on_message(&self.0, connection, handle, msg) 559 } 560 561 fn on_disconnect(&self, connection: &Self::Connection) { 562 <$inner as $crate::Service>::on_disconnect(&self.0, connection) 563 } 564 } 565 }; 566 567 (@unbuffered $wrapper:ident $inner:ty) => { 568 impl $crate::UnbufferedService for $wrapper { 569 type Connection = <$inner as $crate::UnbufferedService>::Connection; 570 571 fn on_connect( 572 &self, 573 port: &$crate::PortCfg, 574 handle: &$crate::Handle, 575 peer: &$crate::Uuid, 576 ) -> $crate::Result<$crate::ConnectResult<Self::Connection>> { 577 <$inner as $crate::UnbufferedService>::on_connect(&self.0, port, handle, peer) 578 } 579 580 fn on_message( 581 &self, 582 connection: &Self::Connection, 583 handle: &$crate::Handle, 584 buffer: &mut [u8], 585 ) -> $crate::Result<$crate::MessageResult> { 586 <$inner as $crate::UnbufferedService>::on_message(&self.0, connection, handle, buffer) 587 } 588 589 fn on_disconnect(&self, connection: &Self::Connection) { 590 <$inner as $crate::UnbufferedService>::on_disconnect(&self.0, connection) 591 } 592 593 fn max_message_length(&self) -> usize { 594 <$inner as $crate::UnbufferedService>::max_message_length(&self.0) 595 } 596 } 597 }; 598 } 599 600 pub trait Dispatcher { 601 /// Generic type to association with a connection. `on_connect()` should 602 /// create this type for a successful connection. 603 type Connection; 604 605 /// Called when a client connects 606 /// 607 /// Returns either `Ok(Accept(Connection))` if the connection should be 608 /// accepted or `Ok(CloseConnection)` if the connection should be closed. on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>609 fn on_connect( 610 &self, 611 port: &PortCfg, 612 handle: &Handle, 613 peer: &Uuid, 614 ) -> Result<ConnectResult<Self::Connection>>; 615 616 /// Called when the service receives a message. 617 /// 618 /// The service manager handles deserializing the message, which is then 619 /// passed to this callback. 620 /// 621 /// Should return `Ok(MaintainConnection)` if the connection should be kept open. The 622 /// connection will be closed if `Ok(CloseConnection)` or `Err(_)` is returned. on_message( &self, connection: &Self::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>623 fn on_message( 624 &self, 625 connection: &Self::Connection, 626 handle: &Handle, 627 buffer: &mut [u8], 628 ) -> Result<MessageResult>; 629 630 /// Called when the client closes a connection. on_disconnect(&self, _connection: &Self::Connection)631 fn on_disconnect(&self, _connection: &Self::Connection) {} 632 633 /// Get the list of ports this dispatcher handles. port_configurations(&self) -> &[PortCfg]634 fn port_configurations(&self) -> &[PortCfg]; 635 636 /// Get the maximum possible length of any message handled by this 637 /// dispatcher. max_message_length(&self) -> usize638 fn max_message_length(&self) -> usize; 639 } 640 641 // Implementation of a static dispatcher for services with only a single message 642 // type. 643 pub struct SingleDispatcher<S: Service> { 644 service: S, 645 ports: [PortCfg; 1], 646 } 647 648 impl<S: Service> SingleDispatcher<S> { new(service: S, port: PortCfg) -> Self649 fn new(service: S, port: PortCfg) -> Self { 650 Self { service, ports: [port] } 651 } 652 } 653 654 impl<S: Service> Dispatcher for SingleDispatcher<S> { 655 type Connection = S::Connection; 656 on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>657 fn on_connect( 658 &self, 659 port: &PortCfg, 660 handle: &Handle, 661 peer: &Uuid, 662 ) -> Result<ConnectResult<Self::Connection>> { 663 self.service.on_connect(port, handle, peer) 664 } 665 on_message( &self, connection: &Self::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>666 fn on_message( 667 &self, 668 connection: &Self::Connection, 669 handle: &Handle, 670 buffer: &mut [u8], 671 ) -> Result<MessageResult> { 672 let mut handles: [Option<Handle>; MAX_MSG_HANDLES] = Default::default(); 673 let (byte_count, handle_count) = handle.recv_vectored(&mut [buffer], &mut handles)?; 674 let msg = S::Message::deserialize(&buffer[..byte_count], &mut handles[..handle_count]) 675 .map_err(|e| { 676 error!("Could not parse message: {:?}", e); 677 TipcError::InvalidData 678 })?; 679 self.service.on_message(connection, handle, msg) 680 } 681 on_disconnect(&self, connection: &Self::Connection)682 fn on_disconnect(&self, connection: &Self::Connection) { 683 self.service.on_disconnect(connection) 684 } 685 max_message_length(&self) -> usize686 fn max_message_length(&self) -> usize { 687 S::Message::MAX_SERIALIZED_SIZE 688 } 689 port_configurations(&self) -> &[PortCfg]690 fn port_configurations(&self) -> &[PortCfg] { 691 &self.ports 692 } 693 } 694 695 // Implementation of a static dispatcher for unbuffered services. 696 pub struct SingleUnbufferedDispatcher<S: UnbufferedService> { 697 service: S, 698 ports: [PortCfg; 1], 699 } 700 701 impl<S: UnbufferedService> SingleUnbufferedDispatcher<S> { new(service: S, port: PortCfg) -> Self702 fn new(service: S, port: PortCfg) -> Self { 703 Self { service, ports: [port] } 704 } 705 } 706 707 impl<S: UnbufferedService> Dispatcher for SingleUnbufferedDispatcher<S> { 708 type Connection = S::Connection; 709 on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>710 fn on_connect( 711 &self, 712 port: &PortCfg, 713 handle: &Handle, 714 peer: &Uuid, 715 ) -> Result<ConnectResult<Self::Connection>> { 716 self.service.on_connect(port, handle, peer) 717 } 718 on_message( &self, connection: &Self::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>719 fn on_message( 720 &self, 721 connection: &Self::Connection, 722 handle: &Handle, 723 buffer: &mut [u8], 724 ) -> Result<MessageResult> { 725 self.service.on_message(connection, handle, buffer) 726 } 727 on_disconnect(&self, connection: &Self::Connection)728 fn on_disconnect(&self, connection: &Self::Connection) { 729 self.service.on_disconnect(connection) 730 } 731 max_message_length(&self) -> usize732 fn max_message_length(&self) -> usize { 733 self.service.max_message_length() 734 } 735 port_configurations(&self) -> &[PortCfg]736 fn port_configurations(&self) -> &[PortCfg] { 737 &self.ports 738 } 739 } 740 741 /// Create a new service dispatcher that can handle a specified set of service 742 /// types. 743 /// 744 /// This macro creates a multi-service dispatcher that holds different types of 745 /// services that should share the same event loop and dispatches to the 746 /// relevant service based on the connection port. Services must implement the 747 /// [`Service`] trait. An instance of this dispatcher must have a single const 748 /// usize parameter specifying how many ports the dispatcher will handle. 749 /// This macro has limited lifetime support. A single lifetime can be 750 /// used for the ServiceDispatcher enum and the included services (see the 751 /// supported definition in the Examples section). 752 /// 753 /// # Examples 754 /// ``` 755 /// service_dispatcher! { 756 /// enum ServiceDispatcher { 757 /// Service1, 758 /// Service2, 759 /// } 760 /// } 761 /// 762 /// // Create a new dispatcher that handles two ports 763 /// let dispatcher = ServiceDispatcher::<2>::new() 764 /// .expect("Could not allocate service dispatcher"); 765 /// 766 /// let cfg = PortCfg::new(&"com.android.trusty.test_port1).unwrap(); 767 /// dispatcher.add_service(Rc::new(Service1), cfg).expect("Could not add service 1"); 768 /// 769 /// let cfg = PortCfg::new(&"com.android.trusty.test_port2).unwrap(); 770 /// dispatcher.add_service(Rc::new(Service2), cfg).expect("Could not add service 2"); 771 /// ``` 772 /// 773 /// ## defining a dispatcher with multiple lifetimes 774 /// ``` 775 /// service_dispatcher! { 776 /// enum ServiceDispatcher<'a> { 777 /// Service1<'a>, 778 /// Service2<'a>, 779 /// } 780 /// } 781 /// ``` 782 #[macro_export] 783 macro_rules! service_dispatcher { 784 (enum $name:ident $(<$elt: lifetime>)? {$($service:ident $(<$slt: lifetime>)? ),+ $(,)*}) => { 785 /// Dispatcher that routes incoming messages to the correct server based on what 786 /// port the message was sent to. 787 /// 788 /// This dispatcher adapts multiple different server types that expect different 789 /// message formats for the same [`Manager`]. By using this dispatcher, 790 /// different servers can be bound to different ports using the same event loop 791 /// in the manager. 792 struct $name<$($elt,)? const PORT_COUNT: usize> { 793 ports: arrayvec::ArrayVec::<$crate::PortCfg, PORT_COUNT>, 794 services: arrayvec::ArrayVec::<ServiceKind$(<$elt>)?, PORT_COUNT>, 795 } 796 797 impl<$($elt,)? const PORT_COUNT: usize> $name<$($elt,)? PORT_COUNT> { 798 fn new() -> $crate::Result<Self> { 799 Ok(Self { 800 ports: arrayvec::ArrayVec::<_, PORT_COUNT>::new(), 801 services: arrayvec::ArrayVec::<_, PORT_COUNT>::new(), 802 }) 803 } 804 805 fn add_service<T>(&mut self, service: alloc::rc::Rc<T>, port: $crate::PortCfg) -> $crate::Result<()> 806 where ServiceKind$(<$elt>)? : From<alloc::rc::Rc<T>> { 807 if self.ports.is_full() || self.services.is_full() { 808 return Err($crate::TipcError::OutOfBounds); 809 } 810 // SAFETY: We check the size above 811 unsafe { 812 self.ports.push_unchecked(port); 813 self.services.push_unchecked(service.into()); 814 } 815 Ok(()) 816 } 817 } 818 819 enum ServiceKind$(<$elt>)? { 820 $($service(alloc::rc::Rc<$service$(<$slt>)?>)),+ 821 } 822 823 $( 824 impl$(<$slt>)? From<alloc::rc::Rc<$service$(<$slt>)?>> for ServiceKind$(<$slt>)? { 825 fn from(service: alloc::rc::Rc<$service$(<$slt>)?>) -> Self { 826 ServiceKind::$service(service) 827 } 828 } 829 )+ 830 831 enum ConnectionKind$(<$elt>)? { 832 $($service(<$service$(<$slt>)? as $crate::UnbufferedService>::Connection)),+ 833 } 834 835 impl<$($elt,)? const PORT_COUNT: usize> $crate::Dispatcher for $name<$($elt,)? PORT_COUNT> { 836 type Connection = (usize, ConnectionKind$(<$elt>)?); 837 838 fn on_connect( 839 &self, 840 port: &$crate::PortCfg, 841 handle: &$crate::Handle, 842 peer: &$crate::Uuid, 843 ) -> $crate::Result<$crate::ConnectResult<Self::Connection>> { 844 let port_idx = self.ports.iter() 845 .position(|cfg| cfg == port) 846 .ok_or($crate::TipcError::InvalidPort)?; 847 848 match &self.services[port_idx] { 849 $(ServiceKind::$service(s) => { 850 $crate::UnbufferedService::on_connect(&**s, port, handle, peer) 851 .map(|c| c.map(|c| (port_idx, ConnectionKind::$service(c)))) 852 })+ 853 } 854 } 855 856 fn on_message( 857 &self, 858 connection: &Self::Connection, 859 handle: &$crate::Handle, 860 buffer: &mut [u8], 861 ) -> $crate::Result<$crate::MessageResult> { 862 match &self.services[connection.0] { 863 $(ServiceKind::$service(s) => { 864 if let ConnectionKind::$service(conn) = &connection.1 { 865 $crate::UnbufferedService::on_message(&**s, conn, handle, buffer) 866 } else { 867 Err($crate::TipcError::InvalidData) 868 } 869 })* 870 } 871 } 872 873 fn on_disconnect(&self, connection: &Self::Connection) { 874 match &self.services[connection.0] { 875 $(ServiceKind::$service(s) => { 876 if let ConnectionKind::$service(conn) = &connection.1 { 877 $crate::UnbufferedService::on_disconnect(&**s, conn) 878 } 879 })* 880 } 881 } 882 883 fn port_configurations(&self) -> &[$crate::PortCfg] { 884 self.ports.as_slice() 885 } 886 887 fn max_message_length(&self) -> usize { 888 self.services.iter().map(|s| { 889 match s { 890 $(ServiceKind::$service(service) => { 891 <$service as $crate::UnbufferedService>::max_message_length(&**service) 892 })+ 893 } 894 }).max().unwrap_or(0usize) 895 } 896 } 897 }; 898 899 (@make_none $service:ident) => { None }; 900 } 901 902 /// A manager that handles the IPC event loop and dispatches connections and 903 /// messages to a generic service. 904 pub struct Manager< 905 D: Dispatcher, 906 B: AsMut<[u8]> + AsRef<[u8]>, 907 const PORT_COUNT: usize, 908 const MAX_CONNECTION_COUNT: usize, 909 > { 910 dispatcher: D, 911 handle_set: HandleSet<D, PORT_COUNT, MAX_CONNECTION_COUNT>, 912 buffer: B, 913 } 914 915 impl< 916 S: Service, 917 B: AsMut<[u8]> + AsRef<[u8]>, 918 const PORT_COUNT: usize, 919 const MAX_CONNECTION_COUNT: usize, 920 > Manager<SingleDispatcher<S>, B, PORT_COUNT, MAX_CONNECTION_COUNT> 921 { 922 /// Create a new service manager for the given service and port. 923 /// 924 /// The manager will receive data into the buffer `B`, so this buffer needs 925 /// to be at least as large as the largest message this service can handle. 926 /// 927 /// # Examples 928 /// 929 /// ``` 930 /// struct MyService; 931 /// 932 /// impl Service for MyService { 933 /// type Connection = (); 934 /// type Message = (); 935 /// 936 /// fn on_connect( 937 /// &self, 938 /// _port: &PortCfg, 939 /// _handle: &Handle, 940 /// _peer: &Uuid, 941 /// ) -> Result<ConnectResult<Self::Connection>> { 942 /// Ok(ConnectResult::Accept(())) 943 /// } 944 /// 945 /// fn on_message( 946 /// &self, 947 /// _connection: &Self::Connection, 948 /// _handle: &Handle, 949 /// _msg: Self::Message, 950 /// ) -> Result<MessageResult> { 951 /// Ok(MessageResult::MaintainConnection) 952 /// } 953 /// } 954 /// 955 /// let service = MyService; 956 /// let cfg = PortCfg::new("com.android.trusty.rust_port_test"); 957 /// let buffer = [0u8; 4096]; 958 /// let mut manager = Manager::<_, _, 1, 1>::new(service, &[cfg], buffer); 959 /// 960 /// manager.run_event_loop() 961 /// .expect("Service manager encountered an error"); 962 /// ``` new(service: S, port_cfg: PortCfg, buffer: B) -> Result<Self>963 pub fn new(service: S, port_cfg: PortCfg, buffer: B) -> Result<Self> { 964 let dispatcher = SingleDispatcher::new(service, port_cfg); 965 Self::new_with_dispatcher(dispatcher, buffer) 966 } 967 } 968 969 impl<S: UnbufferedService, const PORT_COUNT: usize, const MAX_CONNECTION_COUNT: usize> 970 Manager<SingleUnbufferedDispatcher<S>, [u8; 0], PORT_COUNT, MAX_CONNECTION_COUNT> 971 { 972 /// Create a new unbuffered service manager for the given service and port. 973 /// 974 /// The newly created manager will not have an internal buffer. 975 /// The service is responsible for reading messages explicitly from the handler. new_unbuffered(service: S, port_cfg: PortCfg) -> Result<Self>976 pub fn new_unbuffered(service: S, port_cfg: PortCfg) -> Result<Self> { 977 let dispatcher = SingleUnbufferedDispatcher::new(service, port_cfg); 978 Self::new_with_dispatcher(dispatcher, []) 979 } 980 } 981 982 impl< 983 D: Dispatcher, 984 B: AsMut<[u8]> + AsRef<[u8]>, 985 const PORT_COUNT: usize, 986 const MAX_CONNECTION_COUNT: usize, 987 > Manager<D, B, PORT_COUNT, MAX_CONNECTION_COUNT> 988 { 989 /// Create a manager that can handle multiple services and ports 990 /// 991 /// A dispatcher handles mapping connections to services and parsing 992 /// messages for the relevant service depending on which port the connection 993 /// was made to. This allows multiple distinct services, each with their own 994 /// message format and port to share the same event loop in the manager. 995 /// 996 /// See [`service_dispatcher!`] for details on how to create a dispatcher 997 /// for use with this API. 998 /// 999 /// [`service_dispatcher!`]: crate::service_dispatcher 1000 /// 1001 /// # Examples 1002 /// ``` 1003 /// service_dispatcher! { 1004 /// enum ServiceDispatcher { 1005 /// Service1, 1006 /// Service2, 1007 /// } 1008 /// } 1009 /// 1010 /// // Create a new dispatcher that handles two ports 1011 /// let dispatcher = ServiceDispatcher::<2>::new() 1012 /// .expect("Could not allocate service dispatcher"); 1013 /// 1014 /// let cfg = PortCfg::new(&"com.android.trusty.test_port1).unwrap(); 1015 /// dispatcher.add_service(Rc::new(Service1), cfg).expect("Could not add service 1"); 1016 /// 1017 /// let cfg = PortCfg::new(&"com.android.trusty.test_port2).unwrap(); 1018 /// dispatcher.add_service(Rc::new(Service2), cfg).expect("Could not add service 2"); 1019 /// 1020 /// Manager::<_, _, 2, 4>::new_with_dispatcher(dispatcher, [0u8; 4096]) 1021 /// .expect("Could not create service manager") 1022 /// .run_event_loop() 1023 /// .expect("Service manager exited unexpectedly"); 1024 /// ``` new_with_dispatcher(dispatcher: D, buffer: B) -> Result<Self>1025 pub fn new_with_dispatcher(dispatcher: D, buffer: B) -> Result<Self> { 1026 if buffer.as_ref().len() < dispatcher.max_message_length() { 1027 return Err(TipcError::NotEnoughBuffer); 1028 } 1029 1030 let ports: Vec<Rc<Channel<D>>> = dispatcher 1031 .port_configurations() 1032 .iter() 1033 .map(Channel::try_new_port) 1034 .collect::<Result<_>>()?; 1035 let ports: [Rc<Channel<D>>; PORT_COUNT] = ports 1036 .try_into() 1037 .expect("This is impossible. Array size must match expected PORT_COUNT"); 1038 let handle_set = HandleSet::try_new(ports)?; 1039 1040 Ok(Self { dispatcher, handle_set, buffer }) 1041 } 1042 1043 /// Run the service event loop. 1044 /// 1045 /// Only returns if an error occurs. run_event_loop(mut self) -> Result<()>1046 pub fn run_event_loop(mut self) -> Result<()> { 1047 use trusty_sys::Error; 1048 1049 loop { 1050 // Process the next incoming event, extracting any returned error for further 1051 // checking. 1052 let err = match self.event_loop_inner() { 1053 Ok(()) => continue, 1054 Err(err) => err, 1055 }; 1056 1057 // Check if the error is recoverable or not. If the error is not one of a 1058 // limited set of recoverable errors, we break from the event loop. 1059 match err { 1060 // Recoverable errors that are always ignored. 1061 | TipcError::SystemError(Error::TimedOut) 1062 | TipcError::SystemError(Error::ChannelClosed) 1063 1064 // These are always caused by the client and so shouldn't be treated as an 1065 // internal error or cause the event loop to exit. 1066 | TipcError::ChannelClosed 1067 => { 1068 debug!("Recoverable error ignored: {:?}", err) 1069 } 1070 1071 // These are legitimate errors and we should be handling them, but they would be 1072 // better handled lower in the event loop closer to where they originate. If 1073 // they get propagated up here then we can't meaningfully handle them anymore, 1074 // so just log them and continue the loop. 1075 | TipcError::IncompleteWrite { .. } 1076 | TipcError::NotEnoughBuffer 1077 | TipcError::Busy 1078 => { 1079 warn!( 1080 "Received error {:?} in main event loop. This should have been handled closer to where it originated", 1081 err, 1082 ) 1083 } 1084 1085 _ => { 1086 error!("Error occurred while handling incoming event: {:?}", err); 1087 return Err(err); 1088 } 1089 } 1090 } 1091 } 1092 event_loop_inner(&mut self) -> Result<()>1093 fn event_loop_inner(&mut self) -> Result<()> { 1094 let event = self.handle_set.wait(None)?; 1095 // SAFETY: This cookie was previously initialized by the handle set. 1096 // Its lifetime is managed by the handle set, so we are sure that 1097 // the cookie is still valid if the channel is still in this handle 1098 // set. 1099 let channel: Rc<Channel<D>> = unsafe { Channel::from_opaque_ptr(event.cookie) } 1100 .ok_or_else(|| { 1101 // The opaque pointer associated with this handle could not 1102 // be converted back into a `Channel`. This should never 1103 // happen, but throw an internal error if it does. 1104 error!("Connection cookie was invalid"); 1105 TipcError::InvalidData 1106 })?; 1107 self.handler(channel, &event) 1108 } 1109 handler(&mut self, channel: Rc<Channel<D>>, event: &trusty_sys::uevent) -> Result<()>1110 fn handler(&mut self, channel: Rc<Channel<D>>, event: &trusty_sys::uevent) -> Result<()> { 1111 // TODO: Abort on port errors? 1112 match &channel.ty { 1113 ChannelTy::Port(cfg) if event.event & (sys::IPC_HANDLE_POLL_READY as u32) != 0 => { 1114 self.handle_connect(&channel.handle, cfg) 1115 } 1116 ChannelTy::Connection(data) if event.event & (sys::IPC_HANDLE_POLL_MSG as u32) != 0 => { 1117 match self.handle_message(&channel.handle, &data) { 1118 Ok(MessageResult::MaintainConnection) => Ok(()), 1119 Ok(MessageResult::CloseConnection) => { 1120 self.handle_set.close(channel); 1121 Ok(()) 1122 } 1123 Err(e) => { 1124 error!("Could not handle message, closing connection: {:?}", e); 1125 self.handle_set.close(channel); 1126 Ok(()) 1127 } 1128 } 1129 } 1130 ChannelTy::Connection(data) if event.event & (sys::IPC_HANDLE_POLL_HUP as u32) != 0 => { 1131 self.handle_disconnect(&channel.handle, &data); 1132 self.handle_set.close(channel); 1133 Ok(()) 1134 } 1135 1136 // `SEND_UNBLOCKED` means that some previous attempt to send a message was 1137 // blocked and has now become unblocked. This should normally be handled by 1138 // the code trying to send the message, but if the sending code doesn't do so 1139 // then we can end up getting it here. 1140 _ if event.event & (sys::IPC_HANDLE_POLL_SEND_UNBLOCKED as u32) != 0 => { 1141 warn!("Received `SEND_UNBLOCKED` event received in main event loop. This likely means that a sent message was lost somewhere"); 1142 Ok(()) 1143 } 1144 1145 // `NONE` is not an event we should get in practice, but if it does then it 1146 // shouldn't trigger an error. 1147 _ if event.event == (sys::IPC_HANDLE_POLL_NONE as u32) => Ok(()), 1148 1149 // Treat any unrecognized events as errors by default. 1150 _ => { 1151 error!("Could not handle event {}", event.event); 1152 Err(TipcError::UnknownError) 1153 } 1154 } 1155 } 1156 handle_connect(&mut self, handle: &Handle, cfg: &PortCfg) -> Result<()>1157 fn handle_connect(&mut self, handle: &Handle, cfg: &PortCfg) -> Result<()> { 1158 let mut peer = MaybeUninit::zeroed(); 1159 // SAFETY: syscall. The port owns its handle, so it is still valid as 1160 // a raw fd. The peer structure outlives this call and is mutably 1161 // borrowed by the call to initialize the structure's data. 1162 let rc = unsafe { trusty_sys::accept(handle.as_raw_fd(), peer.as_mut_ptr()) as i32 }; 1163 let connection_handle = Handle::from_raw(rc)?; 1164 // SAFETY: accept did not return an error, so it has successfully 1165 // initialized the peer structure. 1166 let peer = unsafe { Uuid(peer.assume_init()) }; 1167 1168 // TODO: Implement access control 1169 1170 let connection_data = self.dispatcher.on_connect(&cfg, &connection_handle, &peer)?; 1171 if let ConnectResult::Accept(data) = connection_data { 1172 let connection_channel = Channel::try_new_connection(connection_handle, data)?; 1173 self.handle_set.add_connection(connection_channel)?; 1174 } 1175 1176 Ok(()) 1177 } 1178 handle_message(&mut self, handle: &Handle, data: &D::Connection) -> Result<MessageResult>1179 fn handle_message(&mut self, handle: &Handle, data: &D::Connection) -> Result<MessageResult> { 1180 self.dispatcher.on_message(data, handle, self.buffer.as_mut()) 1181 } 1182 handle_disconnect(&mut self, _handle: &Handle, data: &D::Connection)1183 fn handle_disconnect(&mut self, _handle: &Handle, data: &D::Connection) { 1184 self.dispatcher.on_disconnect(data); 1185 } 1186 } 1187 1188 #[cfg(test)] 1189 mod test { 1190 use super::{PortCfg, Service}; 1191 use crate::handle::test::{first_free_handle_index, MAX_USER_HANDLES}; 1192 use crate::{ 1193 ConnectResult, Deserialize, Handle, Manager, MessageResult, Result, Serialize, Serializer, 1194 TipcError, UnbufferedService, Uuid, 1195 }; 1196 use test::{expect, expect_eq}; 1197 use trusty_std::alloc::FallibleVec; 1198 use trusty_std::ffi::{CString, FallibleCString}; 1199 use trusty_std::format; 1200 use trusty_std::rc::Rc; 1201 use trusty_std::vec::Vec; 1202 use trusty_sys::Error; 1203 1204 /// Maximum length of port path name 1205 const MAX_PORT_PATH_LEN: usize = 64; 1206 1207 /// Maximum number of buffers per port 1208 const MAX_PORT_BUF_NUM: u32 = 64; 1209 1210 /// Maximum size of port buffer 1211 const MAX_PORT_BUF_SIZE: u32 = 4096; 1212 1213 const SRV_PATH_BASE: &str = "com.android.ipc-unittest"; 1214 1215 impl Service for () { 1216 type Connection = (); 1217 type Message = (); 1218 on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1219 fn on_connect( 1220 &self, 1221 _port: &PortCfg, 1222 _handle: &Handle, 1223 _peer: &Uuid, 1224 ) -> Result<ConnectResult<Self::Connection>> { 1225 Ok(ConnectResult::Accept(())) 1226 } 1227 on_message( &self, _connection: &Self::Connection, _handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1228 fn on_message( 1229 &self, 1230 _connection: &Self::Connection, 1231 _handle: &Handle, 1232 _msg: Self::Message, 1233 ) -> Result<MessageResult> { 1234 Ok(MessageResult::MaintainConnection) 1235 } 1236 } 1237 1238 type Channel = super::Channel<super::SingleDispatcher<()>>; 1239 1240 #[test] port_create_negative()1241 fn port_create_negative() { 1242 let path = [0u8; 0]; 1243 1244 expect_eq!( 1245 Channel::try_new_port(&PortCfg::new_raw(CString::try_new(&path[..]).unwrap())).err(), 1246 Some(TipcError::SystemError(Error::InvalidArgs)), 1247 "empty server path", 1248 ); 1249 1250 let mut path = format!("{}.port", SRV_PATH_BASE); 1251 1252 let cfg = PortCfg::new(&path).unwrap().msg_queue_len(0); 1253 expect_eq!( 1254 Channel::try_new_port(&cfg).err(), 1255 Some(TipcError::SystemError(Error::InvalidArgs)), 1256 "no buffers", 1257 ); 1258 1259 let cfg = PortCfg::new(&path).unwrap().msg_max_size(0); 1260 expect_eq!( 1261 Channel::try_new_port(&cfg).err(), 1262 Some(TipcError::SystemError(Error::InvalidArgs)), 1263 "zero buffer size", 1264 ); 1265 1266 let cfg = PortCfg::new(&path).unwrap().msg_queue_len(MAX_PORT_BUF_NUM * 100); 1267 expect_eq!( 1268 Channel::try_new_port(&cfg).err(), 1269 Some(TipcError::SystemError(Error::InvalidArgs)), 1270 "large number of buffers", 1271 ); 1272 1273 let cfg = PortCfg::new(&path).unwrap().msg_max_size(MAX_PORT_BUF_SIZE * 100); 1274 expect_eq!( 1275 Channel::try_new_port(&cfg).err(), 1276 Some(TipcError::SystemError(Error::InvalidArgs)), 1277 "large buffers size", 1278 ); 1279 1280 while path.len() < MAX_PORT_PATH_LEN + 16 { 1281 path.push('a'); 1282 } 1283 1284 let cfg = PortCfg::new(&path).unwrap(); 1285 expect_eq!( 1286 Channel::try_new_port(&cfg).err(), 1287 Some(TipcError::SystemError(Error::InvalidArgs)), 1288 "path is too long", 1289 ); 1290 } 1291 1292 #[test] port_create()1293 fn port_create() { 1294 let mut channels: Vec<Rc<Channel>> = Vec::new(); 1295 1296 for i in first_free_handle_index()..MAX_USER_HANDLES - 1 { 1297 let path = format!("{}.port.{}{}", SRV_PATH_BASE, "test", i); 1298 let cfg = PortCfg::new(path).unwrap(); 1299 let channel = Channel::try_new_port(&cfg); 1300 expect!(channel.is_ok(), "create ports"); 1301 channels.try_push(channel.unwrap()).unwrap(); 1302 1303 expect_eq!( 1304 Channel::try_new_port(&cfg).err(), 1305 Some(TipcError::SystemError(Error::AlreadyExists)), 1306 "collide with existing port", 1307 ); 1308 } 1309 1310 // Creating one more port should succeed 1311 let path = format!("{}.port.{}{}", SRV_PATH_BASE, "test", MAX_USER_HANDLES - 1); 1312 let cfg = PortCfg::new(path).unwrap(); 1313 let channel = Channel::try_new_port(&cfg); 1314 expect!(channel.is_ok(), "create ports"); 1315 channels.try_push(channel.unwrap()).unwrap(); 1316 1317 // but creating colliding port should fail with different error code 1318 // because we actually exceeded max number of handles instead of 1319 // colliding with an existing path 1320 expect_eq!( 1321 Channel::try_new_port(&cfg).err(), 1322 Some(TipcError::SystemError(Error::NoResources)), 1323 "collide with existing port", 1324 ); 1325 1326 let path = format!("{}.port.{}{}", SRV_PATH_BASE, "test", MAX_USER_HANDLES); 1327 let cfg = PortCfg::new(path).unwrap(); 1328 expect_eq!( 1329 Channel::try_new_port(&cfg).err(), 1330 Some(TipcError::SystemError(Error::NoResources)), 1331 "max number of ports reached", 1332 ); 1333 } 1334 1335 #[test] wait_on_port()1336 fn wait_on_port() { 1337 let mut channels: Vec<Rc<Channel>> = Vec::new(); 1338 1339 for i in first_free_handle_index()..MAX_USER_HANDLES { 1340 let path = format!("{}.port.{}{}", SRV_PATH_BASE, "test", i); 1341 let cfg = PortCfg::new(path).unwrap(); 1342 let channel = Channel::try_new_port(&cfg); 1343 expect!(channel.is_ok(), "create ports"); 1344 channels.try_push(channel.unwrap()).unwrap(); 1345 } 1346 1347 for chan in &channels { 1348 expect_eq!( 1349 chan.handle.wait(Some(0)).err(), 1350 Some(TipcError::SystemError(Error::TimedOut)), 1351 "zero timeout", 1352 ); 1353 1354 expect_eq!( 1355 chan.handle.wait(Some(100)).err(), 1356 Some(TipcError::SystemError(Error::TimedOut)), 1357 "non-zero timeout", 1358 ); 1359 } 1360 } 1361 1362 impl<'s> Serialize<'s> for i32 { serialize<'a: 's, S: Serializer<'s>>( &'a self, serializer: &mut S, ) -> core::result::Result<S::Ok, S::Error>1363 fn serialize<'a: 's, S: Serializer<'s>>( 1364 &'a self, 1365 serializer: &mut S, 1366 ) -> core::result::Result<S::Ok, S::Error> { 1367 unsafe { serializer.serialize_as_bytes(self) } 1368 } 1369 } 1370 1371 impl Deserialize for i32 { 1372 type Error = TipcError; 1373 1374 const MAX_SERIALIZED_SIZE: usize = 4; 1375 deserialize( bytes: &[u8], _handles: &mut [Option<Handle>], ) -> core::result::Result<Self, Self::Error>1376 fn deserialize( 1377 bytes: &[u8], 1378 _handles: &mut [Option<Handle>], 1379 ) -> core::result::Result<Self, Self::Error> { 1380 Ok(i32::from_ne_bytes(bytes[0..4].try_into().map_err(|_| TipcError::OutOfBounds)?)) 1381 } 1382 } 1383 1384 struct Service1; 1385 1386 impl Service for Service1 { 1387 type Connection = (); 1388 type Message = (); 1389 on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1390 fn on_connect( 1391 &self, 1392 _port: &PortCfg, 1393 _handle: &Handle, 1394 _peer: &Uuid, 1395 ) -> Result<ConnectResult<Self::Connection>> { 1396 Ok(ConnectResult::Accept(())) 1397 } 1398 on_message( &self, _connection: &Self::Connection, handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1399 fn on_message( 1400 &self, 1401 _connection: &Self::Connection, 1402 handle: &Handle, 1403 _msg: Self::Message, 1404 ) -> Result<MessageResult> { 1405 handle.send(&1i32)?; 1406 Ok(MessageResult::MaintainConnection) 1407 } 1408 } 1409 1410 struct Service2; 1411 1412 impl Service for Service2 { 1413 type Connection = (); 1414 type Message = (); 1415 on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1416 fn on_connect( 1417 &self, 1418 _port: &PortCfg, 1419 _handle: &Handle, 1420 _peer: &Uuid, 1421 ) -> Result<ConnectResult<Self::Connection>> { 1422 Ok(ConnectResult::Accept(())) 1423 } 1424 on_message( &self, _connection: &Self::Connection, handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1425 fn on_message( 1426 &self, 1427 _connection: &Self::Connection, 1428 handle: &Handle, 1429 _msg: Self::Message, 1430 ) -> Result<MessageResult> { 1431 handle.send(&2i32)?; 1432 Ok(MessageResult::MaintainConnection) 1433 } 1434 } 1435 1436 struct Service3; 1437 1438 impl UnbufferedService for Service3 { 1439 type Connection = (); 1440 on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1441 fn on_connect( 1442 &self, 1443 _port: &PortCfg, 1444 _handle: &Handle, 1445 _peer: &Uuid, 1446 ) -> Result<ConnectResult<Self::Connection>> { 1447 Ok(ConnectResult::Accept(())) 1448 } 1449 on_message( &self, _connection: &Self::Connection, handle: &Handle, _buffer: &mut [u8], ) -> Result<MessageResult>1450 fn on_message( 1451 &self, 1452 _connection: &Self::Connection, 1453 handle: &Handle, 1454 _buffer: &mut [u8], 1455 ) -> Result<MessageResult> { 1456 handle.send(&3i32)?; 1457 Ok(MessageResult::MaintainConnection) 1458 } 1459 } 1460 1461 wrap_service!(WrappedService2(Service2: Service)); 1462 wrap_service!(WrappedService3(Service3: UnbufferedService)); 1463 1464 service_dispatcher! { 1465 enum TestServiceDispatcher { 1466 Service1, 1467 Service2, 1468 Service3, 1469 WrappedService2, 1470 WrappedService3, 1471 } 1472 } 1473 1474 #[test] multiple_services()1475 fn multiple_services() { 1476 let mut dispatcher = TestServiceDispatcher::<5>::new().unwrap(); 1477 1478 let path1 = format!("{}.port.{}", SRV_PATH_BASE, "testService1"); 1479 let cfg = PortCfg::new(&path1).unwrap(); 1480 dispatcher.add_service(Rc::new(Service1), cfg).expect("Could not add service 1"); 1481 1482 let path2 = format!("{}.port.{}", SRV_PATH_BASE, "testService2"); 1483 let cfg = PortCfg::new(&path2).unwrap(); 1484 dispatcher.add_service(Rc::new(Service2), cfg).expect("Could not add service 2"); 1485 1486 let path = format!("{}.port.{}", SRV_PATH_BASE, "testService3"); 1487 let cfg = PortCfg::new(&path).unwrap(); 1488 dispatcher.add_service(Rc::new(Service3), cfg).expect("Could not add service 3"); 1489 1490 let path = format!("{}.port.{}", SRV_PATH_BASE, "testWrappedService2"); 1491 let cfg = PortCfg::new(&path).unwrap(); 1492 dispatcher 1493 .add_service(Rc::new(WrappedService2(Service2)), cfg) 1494 .expect("Could not add wrapped service 2"); 1495 1496 let path = format!("{}.port.{}", SRV_PATH_BASE, "testWrappedService3"); 1497 let cfg = PortCfg::new(&path).unwrap(); 1498 dispatcher 1499 .add_service(Rc::new(WrappedService3(Service3)), cfg) 1500 .expect("Could not add wrapped service 3"); 1501 1502 let buffer = [0u8; 4096]; 1503 Manager::<_, _, 5, 4>::new_with_dispatcher(dispatcher, buffer) 1504 .expect("Could not create service manager"); 1505 } 1506 1507 #[test] unbuffered_service()1508 fn unbuffered_service() { 1509 let path = format!("{}.port.{}", SRV_PATH_BASE, "unbufferedService"); 1510 let cfg = PortCfg::new(&path).unwrap(); 1511 Manager::<_, _, 1, 4>::new_unbuffered(Service3, cfg) 1512 .expect("Could not create service manager"); 1513 } 1514 } 1515 1516 #[cfg(test)] 1517 mod multiservice_with_lifetimes_tests { 1518 use super::*; 1519 use core::marker::PhantomData; 1520 #[allow(unused)] 1521 use trusty_std::alloc::FallibleVec; 1522 1523 const SRV_PATH_BASE: &str = "com.android.ipc-unittest-lifetimes"; 1524 1525 struct Service1<'a> { 1526 phantom: PhantomData<&'a u32>, 1527 } 1528 1529 impl<'a> Service for Service1<'a> { 1530 type Connection = (); 1531 type Message = (); 1532 on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1533 fn on_connect( 1534 &self, 1535 _port: &PortCfg, 1536 _handle: &Handle, 1537 _peer: &Uuid, 1538 ) -> Result<ConnectResult<Self::Connection>> { 1539 Ok(ConnectResult::Accept(())) 1540 } 1541 on_message( &self, _connection: &Self::Connection, handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1542 fn on_message( 1543 &self, 1544 _connection: &Self::Connection, 1545 handle: &Handle, 1546 _msg: Self::Message, 1547 ) -> Result<MessageResult> { 1548 handle.send(&2i32)?; 1549 Ok(MessageResult::MaintainConnection) 1550 } 1551 } 1552 1553 struct Service2<'a> { 1554 phantom: PhantomData<&'a u32>, 1555 } 1556 1557 impl<'a> Service for Service2<'a> { 1558 type Connection = (); 1559 type Message = (); 1560 on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1561 fn on_connect( 1562 &self, 1563 _port: &PortCfg, 1564 _handle: &Handle, 1565 _peer: &Uuid, 1566 ) -> Result<ConnectResult<Self::Connection>> { 1567 Ok(ConnectResult::Accept(())) 1568 } 1569 on_message( &self, _connection: &Self::Connection, handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1570 fn on_message( 1571 &self, 1572 _connection: &Self::Connection, 1573 handle: &Handle, 1574 _msg: Self::Message, 1575 ) -> Result<MessageResult> { 1576 handle.send(&2i32)?; 1577 Ok(MessageResult::MaintainConnection) 1578 } 1579 } 1580 1581 service_dispatcher! { 1582 enum TestServiceLifetimeDispatcher<'a> { 1583 Service1<'a>, 1584 Service2<'a>, 1585 } 1586 } 1587 1588 #[test] manager_creation()1589 fn manager_creation() { 1590 let mut dispatcher = TestServiceLifetimeDispatcher::<2>::new().unwrap(); 1591 1592 let path1 = format!("{}.port.{}", SRV_PATH_BASE, "testService1"); 1593 let cfg = PortCfg::new(&path1).unwrap(); 1594 dispatcher 1595 .add_service(Rc::new(Service1 { phantom: PhantomData }), cfg) 1596 .expect("Could not add service 1"); 1597 1598 let path2 = format!("{}.port.{}", SRV_PATH_BASE, "testService2"); 1599 let cfg = PortCfg::new(&path2).unwrap(); 1600 dispatcher 1601 .add_service(Rc::new(Service2 { phantom: PhantomData }), cfg) 1602 .expect("Could not add service 2"); 1603 1604 let buffer = [0u8; 4096]; 1605 Manager::<_, _, 2, 4>::new_with_dispatcher(dispatcher, buffer) 1606 .expect("Could not create service manager"); 1607 } 1608 } 1609 1610 #[cfg(test)] 1611 mod uuid_tests { 1612 use super::Uuid; 1613 use test::{expect, expect_eq}; 1614 1615 #[test] uuid_parsing()1616 fn uuid_parsing() { 1617 let uuid = Uuid::new(0, 0, 0, [0; 8]); 1618 let uuid_string = "00000000-0000-0000-0000-000000000000".to_string(); 1619 expect_eq!(uuid.to_string(), uuid_string); 1620 let uuid_from_str = Uuid::new_from_string(&uuid_string); 1621 expect!(uuid_from_str.is_ok(), "couldn't parse uuid string"); 1622 let uuid_from_str = uuid_from_str.unwrap(); 1623 expect_eq!(uuid, uuid_from_str, "uuid should match"); 1624 let uuid2 = Uuid::new(1262561249, 51804, 17255, [189, 181, 5, 22, 64, 5, 183, 196]); 1625 let uuid_string_2 = "4b4127e1-ca5c-4367-bdb5-05164005b7c4".to_string(); 1626 let uuid2_from_str = Uuid::new_from_string(&uuid_string_2); 1627 expect!(uuid2_from_str.is_ok(), "couldn't parse uuid string"); 1628 let uuid2_from_str = uuid2_from_str.unwrap(); 1629 expect_eq!(uuid2, uuid2_from_str, "uuid should match"); 1630 let bad_uuid_from_str = Uuid::new_from_string("4b4127e1-ca5c-4367-bdb5-05164005b7c45"); 1631 expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string"); 1632 let bad_uuid_from_str = Uuid::new_from_string("4b4127e1-ca5c-4367-bdbq-05164005b7c4"); 1633 expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string"); 1634 let bad_uuid_from_str = Uuid::new_from_string("4b4127e1-ca5c-4367-bdb5005164005b7c4"); 1635 expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string"); 1636 let bad_uuid_from_str = Uuid::new_from_string("4b41-7e1-ca5c-4367-bdb5-05164005b7c4"); 1637 expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string"); 1638 let bad_uuid_from_str = Uuid::new_from_string("4b4127e1-ca5c-4367-bd-b505164005b7c4"); 1639 expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string"); 1640 } 1641 } 1642