1cc290419Sopenharmony_ci/* 2cc290419Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License. 5cc290419Sopenharmony_ci * You may obtain a copy of the License at 6cc290419Sopenharmony_ci * 7cc290419Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8cc290419Sopenharmony_ci * 9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and 13cc290419Sopenharmony_ci * limitations under the License. 14cc290419Sopenharmony_ci */ 15cc290419Sopenharmony_ci//! uds 16cc290419Sopenharmony_ci#![allow(missing_docs)] 17cc290419Sopenharmony_ci#![allow(clippy::missing_safety_doc)] 18cc290419Sopenharmony_ci#[cfg(not(feature = "host"))] 19cc290419Sopenharmony_ciuse crate::utils::hdc_log::*; 20cc290419Sopenharmony_ciuse libc::bind; 21cc290419Sopenharmony_ciuse libc::c_void; 22cc290419Sopenharmony_ciuse libc::{accept4, close, connect}; 23cc290419Sopenharmony_ciuse libc::{c_char, listen, poll, recv, socket, MSG_NOSIGNAL}; 24cc290419Sopenharmony_ciuse libc::{c_int, sa_family_t, sockaddr, sockaddr_un, socklen_t, AF_UNIX}; 25cc290419Sopenharmony_ciuse libc::{eventfd, fcntl, pipe, read, send, socketpair, write, MSG_EOR}; 26cc290419Sopenharmony_ciuse libc::{EFD_CLOEXEC, EFD_NONBLOCK, SOCK_CLOEXEC, SOCK_STREAM}; 27cc290419Sopenharmony_ciuse libc::{POLLERR, POLLHUP, POLLNVAL, POLLRDHUP}; 28cc290419Sopenharmony_ciuse std::io::{self, ErrorKind, Result}; 29cc290419Sopenharmony_ciuse std::mem; 30cc290419Sopenharmony_ci 31cc290419Sopenharmony_ciconst LISTEN_BACKLOG: c_int = 10; 32cc290419Sopenharmony_ciconst MAX_CLIENT_FD_COUNT: usize = 256; 33cc290419Sopenharmony_ci 34cc290419Sopenharmony_ci#[derive(PartialEq, Debug, Clone)] 35cc290419Sopenharmony_cipub struct PollNode { 36cc290419Sopenharmony_ci pub fd: i32, 37cc290419Sopenharmony_ci pub events: i16, 38cc290419Sopenharmony_ci pub revents: i16, 39cc290419Sopenharmony_ci pub ppid: u32, 40cc290419Sopenharmony_ci pub pkg_name: String, 41cc290419Sopenharmony_ci pub is_debug: bool, 42cc290419Sopenharmony_ci} 43cc290419Sopenharmony_ci 44cc290419Sopenharmony_ciimpl PollNode { 45cc290419Sopenharmony_ci pub fn new(fd: i32, ppid: u32, pkg_name: String, is_debug: bool) -> Self { 46cc290419Sopenharmony_ci Self { 47cc290419Sopenharmony_ci fd, 48cc290419Sopenharmony_ci events: POLLNVAL | POLLRDHUP | POLLHUP | POLLERR, 49cc290419Sopenharmony_ci revents: 0, 50cc290419Sopenharmony_ci ppid, 51cc290419Sopenharmony_ci pkg_name, 52cc290419Sopenharmony_ci is_debug, 53cc290419Sopenharmony_ci } 54cc290419Sopenharmony_ci } 55cc290419Sopenharmony_ci} 56cc290419Sopenharmony_ci 57cc290419Sopenharmony_cifn name_index() -> socklen_t { 58cc290419Sopenharmony_ci unsafe { 59cc290419Sopenharmony_ci let total_size = mem::size_of::<sockaddr_un>(); 60cc290419Sopenharmony_ci let name_size = mem::size_of_val(&mem::zeroed::<sockaddr_un>().sun_path); 61cc290419Sopenharmony_ci (total_size - name_size) as socklen_t 62cc290419Sopenharmony_ci } 63cc290419Sopenharmony_ci} 64cc290419Sopenharmony_ci 65cc290419Sopenharmony_ci// const fn as_u8(slice: &[c_char]) -> &[u8] { 66cc290419Sopenharmony_ci// unsafe { &*(slice as *const [c_char] as *const [u8]) } 67cc290419Sopenharmony_ci// } 68cc290419Sopenharmony_ci 69cc290419Sopenharmony_ciconst fn as_char(slice: &[u8]) -> &[c_char] { 70cc290419Sopenharmony_ci unsafe { &*(slice as *const [u8] as *const [c_char]) } 71cc290419Sopenharmony_ci} 72cc290419Sopenharmony_ci 73cc290419Sopenharmony_cipub struct UdsAddr { 74cc290419Sopenharmony_ci addr: sockaddr_un, 75cc290419Sopenharmony_ci len: socklen_t, 76cc290419Sopenharmony_ci} 77cc290419Sopenharmony_ci 78cc290419Sopenharmony_ciimpl Default for UdsAddr { 79cc290419Sopenharmony_ci fn default() -> Self { 80cc290419Sopenharmony_ci let mut addr: sockaddr_un = unsafe { mem::zeroed() }; 81cc290419Sopenharmony_ci addr.sun_family = AF_UNIX as sa_family_t; 82cc290419Sopenharmony_ci Self { 83cc290419Sopenharmony_ci len: name_index(), 84cc290419Sopenharmony_ci addr, 85cc290419Sopenharmony_ci } 86cc290419Sopenharmony_ci } 87cc290419Sopenharmony_ci} 88cc290419Sopenharmony_ci 89cc290419Sopenharmony_ciimpl UdsAddr { 90cc290419Sopenharmony_ci pub fn parse_abstract(name: &[u8]) -> io::Result<Self> { 91cc290419Sopenharmony_ci let mut addr = UdsAddr::default(); 92cc290419Sopenharmony_ci addr.addr.sun_path[1..1 + name.len()].copy_from_slice(as_char(name)); 93cc290419Sopenharmony_ci addr.len = name_index() + 1 + name.len() as socklen_t; 94cc290419Sopenharmony_ci Ok(addr) 95cc290419Sopenharmony_ci } 96cc290419Sopenharmony_ci 97cc290419Sopenharmony_ci pub fn as_raw_general(&self) -> (&sockaddr, socklen_t) { 98cc290419Sopenharmony_ci ( 99cc290419Sopenharmony_ci unsafe { &*(&self.addr as *const sockaddr_un as *const sockaddr) }, 100cc290419Sopenharmony_ci self.len, 101cc290419Sopenharmony_ci ) 102cc290419Sopenharmony_ci } 103cc290419Sopenharmony_ci 104cc290419Sopenharmony_ci pub unsafe fn as_raw_mut_general(&mut self) -> (&mut sockaddr, &mut socklen_t) { 105cc290419Sopenharmony_ci ( 106cc290419Sopenharmony_ci &mut *(&mut self.addr as *mut sockaddr_un as *mut sockaddr), 107cc290419Sopenharmony_ci &mut self.len, 108cc290419Sopenharmony_ci ) 109cc290419Sopenharmony_ci } 110cc290419Sopenharmony_ci} 111cc290419Sopenharmony_ci 112cc290419Sopenharmony_cipub struct UdsServer {} 113cc290419Sopenharmony_ci 114cc290419Sopenharmony_ciimpl UdsServer { 115cc290419Sopenharmony_ci pub fn wrap_socket(socket_type: c_int) -> i32 { 116cc290419Sopenharmony_ci let flags = socket_type | SOCK_CLOEXEC; 117cc290419Sopenharmony_ci unsafe { socket(AF_UNIX, flags, 0) } 118cc290419Sopenharmony_ci } 119cc290419Sopenharmony_ci 120cc290419Sopenharmony_ci pub fn wrap_bind(socket_fd: i32, addr: &UdsAddr) -> Result<()> { 121cc290419Sopenharmony_ci unsafe { 122cc290419Sopenharmony_ci let (addr_raw, len_raw) = addr.as_raw_general(); 123cc290419Sopenharmony_ci loop { 124cc290419Sopenharmony_ci let ret = bind(socket_fd, addr_raw, len_raw); 125cc290419Sopenharmony_ci if ret != -1 { 126cc290419Sopenharmony_ci break Ok(()); 127cc290419Sopenharmony_ci } 128cc290419Sopenharmony_ci crate::error!("bind failed ret : {}", ret); 129cc290419Sopenharmony_ci let err = io::Error::last_os_error(); 130cc290419Sopenharmony_ci if err.kind() != ErrorKind::Interrupted { 131cc290419Sopenharmony_ci break Err(err); 132cc290419Sopenharmony_ci } 133cc290419Sopenharmony_ci } 134cc290419Sopenharmony_ci } 135cc290419Sopenharmony_ci } 136cc290419Sopenharmony_ci 137cc290419Sopenharmony_ci pub fn wrap_listen(socket_fd: i32) -> c_int { 138cc290419Sopenharmony_ci unsafe { listen(socket_fd, LISTEN_BACKLOG) } 139cc290419Sopenharmony_ci } 140cc290419Sopenharmony_ci 141cc290419Sopenharmony_ci pub fn wrap_accept(socket_fd: i32) -> i32 { 142cc290419Sopenharmony_ci let mut addr = UdsAddr::default(); 143cc290419Sopenharmony_ci let capacity = mem::size_of_val(&addr.addr) as socklen_t; 144cc290419Sopenharmony_ci addr.len = capacity; 145cc290419Sopenharmony_ci unsafe { 146cc290419Sopenharmony_ci let (addr_ptr, len_ptr) = addr.as_raw_mut_general(); 147cc290419Sopenharmony_ci accept4(socket_fd, addr_ptr, len_ptr, SOCK_CLOEXEC) 148cc290419Sopenharmony_ci } 149cc290419Sopenharmony_ci } 150cc290419Sopenharmony_ci 151cc290419Sopenharmony_ci pub fn wrap_recv(socket_fd: i32, buffer: &mut [u8]) -> isize { 152cc290419Sopenharmony_ci let ptr = buffer.as_ptr() as *mut c_void; 153cc290419Sopenharmony_ci unsafe { recv(socket_fd, ptr, buffer.len(), MSG_NOSIGNAL) } 154cc290419Sopenharmony_ci } 155cc290419Sopenharmony_ci 156cc290419Sopenharmony_ci pub fn wrap_read(socket_fd: i32, buffer: &mut [u8]) -> isize { 157cc290419Sopenharmony_ci let ptr = buffer.as_ptr() as *mut c_void; 158cc290419Sopenharmony_ci unsafe { read(socket_fd, ptr, buffer.len()) } 159cc290419Sopenharmony_ci } 160cc290419Sopenharmony_ci 161cc290419Sopenharmony_ci pub fn wrap_write(socket_fd: i32, buffer: &[u8]) -> isize { 162cc290419Sopenharmony_ci let ptr = buffer.as_ptr() as *const c_void; 163cc290419Sopenharmony_ci unsafe { write(socket_fd, ptr, buffer.len()) } 164cc290419Sopenharmony_ci } 165cc290419Sopenharmony_ci 166cc290419Sopenharmony_ci pub fn wrap_event_fd() -> i32 { 167cc290419Sopenharmony_ci unsafe { eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK) } 168cc290419Sopenharmony_ci } 169cc290419Sopenharmony_ci 170cc290419Sopenharmony_ci pub fn wrap_write_fd(fd: i32) { 171cc290419Sopenharmony_ci unsafe { 172cc290419Sopenharmony_ci let buf = [1u64; 1]; 173cc290419Sopenharmony_ci let ret = write(fd, buf.as_ptr() as *const c_void, mem::size_of_val(&buf)); 174cc290419Sopenharmony_ci crate::info!("uds wrap_write fd, fd:{}, ret:{}", fd, ret); 175cc290419Sopenharmony_ci } 176cc290419Sopenharmony_ci } 177cc290419Sopenharmony_ci 178cc290419Sopenharmony_ci pub fn wrap_read_fd(fd: i32) { 179cc290419Sopenharmony_ci unsafe { 180cc290419Sopenharmony_ci let buf = [1u64; 1]; 181cc290419Sopenharmony_ci read(fd, buf.as_ptr() as *mut c_void, mem::size_of_val(&buf)); 182cc290419Sopenharmony_ci } 183cc290419Sopenharmony_ci } 184cc290419Sopenharmony_ci 185cc290419Sopenharmony_ci pub fn wrap_poll(fds: &mut [PollNode], size: u32, timeout: i32) -> i32 { 186cc290419Sopenharmony_ci let init_value = unsafe { mem::zeroed() }; 187cc290419Sopenharmony_ci let pollfds: &mut [libc::pollfd; MAX_CLIENT_FD_COUNT] = 188cc290419Sopenharmony_ci &mut [init_value; MAX_CLIENT_FD_COUNT]; 189cc290419Sopenharmony_ci for (index, node) in fds.iter_mut().enumerate() { 190cc290419Sopenharmony_ci if !(0..MAX_CLIENT_FD_COUNT).contains(&index) { 191cc290419Sopenharmony_ci continue; 192cc290419Sopenharmony_ci } 193cc290419Sopenharmony_ci pollfds[index].fd = node.fd; 194cc290419Sopenharmony_ci pollfds[index].events = node.events; 195cc290419Sopenharmony_ci pollfds[index].revents = node.revents; 196cc290419Sopenharmony_ci } 197cc290419Sopenharmony_ci unsafe { 198cc290419Sopenharmony_ci let ret = poll(pollfds.as_mut_ptr(), size as libc::nfds_t, timeout); 199cc290419Sopenharmony_ci crate::info!("uds wrap_poll, poll ret:{}", ret); 200cc290419Sopenharmony_ci if ret == -1 { 201cc290419Sopenharmony_ci ret 202cc290419Sopenharmony_ci } else { 203cc290419Sopenharmony_ci for i in 0..size as usize { 204cc290419Sopenharmony_ci if i >= fds.len() { 205cc290419Sopenharmony_ci break; 206cc290419Sopenharmony_ci } 207cc290419Sopenharmony_ci fds[i].revents = pollfds[i].revents; 208cc290419Sopenharmony_ci fds[i].events = pollfds[i].events; 209cc290419Sopenharmony_ci } 210cc290419Sopenharmony_ci 0 211cc290419Sopenharmony_ci } 212cc290419Sopenharmony_ci } 213cc290419Sopenharmony_ci } 214cc290419Sopenharmony_ci 215cc290419Sopenharmony_ci #[allow(unused)] 216cc290419Sopenharmony_ci pub fn wrap_send(socket_fd: i32, buffer: &[u8]) -> isize { 217cc290419Sopenharmony_ci let ptr = buffer.as_ptr() as *const c_void; 218cc290419Sopenharmony_ci let flags = MSG_NOSIGNAL | MSG_EOR; 219cc290419Sopenharmony_ci unsafe { send(socket_fd, ptr, buffer.len(), flags) } 220cc290419Sopenharmony_ci } 221cc290419Sopenharmony_ci 222cc290419Sopenharmony_ci #[allow(unused)] 223cc290419Sopenharmony_ci pub fn wrap_close(socket_fd: i32) { 224cc290419Sopenharmony_ci unsafe { close(socket_fd) }; 225cc290419Sopenharmony_ci } 226cc290419Sopenharmony_ci 227cc290419Sopenharmony_ci #[allow(unused)] 228cc290419Sopenharmony_ci pub fn wrap_socketpair(socket_type: c_int) -> Result<(i32, i32)> { 229cc290419Sopenharmony_ci let flags = socket_type | SOCK_CLOEXEC; 230cc290419Sopenharmony_ci let mut fd_buf = [-1; 2]; 231cc290419Sopenharmony_ci unsafe { 232cc290419Sopenharmony_ci socketpair(AF_UNIX, flags, 0, fd_buf[..].as_mut_ptr()); 233cc290419Sopenharmony_ci fcntl(fd_buf[1], 100, 20); 234cc290419Sopenharmony_ci } 235cc290419Sopenharmony_ci Ok((fd_buf[0], fd_buf[1])) 236cc290419Sopenharmony_ci } 237cc290419Sopenharmony_ci 238cc290419Sopenharmony_ci #[allow(unused)] 239cc290419Sopenharmony_ci pub fn wrap_pipe() -> Result<(i32, i32)> { 240cc290419Sopenharmony_ci let mut fd_buf = [-1; 2]; 241cc290419Sopenharmony_ci unsafe { 242cc290419Sopenharmony_ci crate::debug!("pipe() begin..."); 243cc290419Sopenharmony_ci let ret = pipe(fd_buf[..].as_mut_ptr()); 244cc290419Sopenharmony_ci crate::debug!("pipe() ret:{}", ret); 245cc290419Sopenharmony_ci if ret >= 0 { 246cc290419Sopenharmony_ci fcntl(fd_buf[1], 100, 20); 247cc290419Sopenharmony_ci } 248cc290419Sopenharmony_ci } 249cc290419Sopenharmony_ci Ok((fd_buf[0], fd_buf[1])) 250cc290419Sopenharmony_ci } 251cc290419Sopenharmony_ci} 252cc290419Sopenharmony_ci 253cc290419Sopenharmony_cipub struct UdsClient {} 254cc290419Sopenharmony_ci 255cc290419Sopenharmony_ciimpl UdsClient { 256cc290419Sopenharmony_ci pub fn wrap_socket(af: i32) -> i32 { 257cc290419Sopenharmony_ci let flags = SOCK_STREAM | SOCK_CLOEXEC; 258cc290419Sopenharmony_ci unsafe { socket(af, flags, 0) } 259cc290419Sopenharmony_ci } 260cc290419Sopenharmony_ci 261cc290419Sopenharmony_ci pub fn wrap_bind(socket_fd: i32, addr: &UdsAddr) -> Result<()> { 262cc290419Sopenharmony_ci unsafe { 263cc290419Sopenharmony_ci let (addr_raw, len_raw) = addr.as_raw_general(); 264cc290419Sopenharmony_ci loop { 265cc290419Sopenharmony_ci let ret = bind(socket_fd, addr_raw, len_raw); 266cc290419Sopenharmony_ci crate::debug!("bind ret : {}", ret); 267cc290419Sopenharmony_ci if ret != -1 { 268cc290419Sopenharmony_ci break Ok(()); 269cc290419Sopenharmony_ci } 270cc290419Sopenharmony_ci let err = io::Error::last_os_error(); 271cc290419Sopenharmony_ci if err.kind() != ErrorKind::Interrupted { 272cc290419Sopenharmony_ci break Err(err); 273cc290419Sopenharmony_ci } 274cc290419Sopenharmony_ci } 275cc290419Sopenharmony_ci } 276cc290419Sopenharmony_ci } 277cc290419Sopenharmony_ci 278cc290419Sopenharmony_ci pub fn wrap_listen(socket_fd: i32) -> c_int { 279cc290419Sopenharmony_ci unsafe { listen(socket_fd, LISTEN_BACKLOG) } 280cc290419Sopenharmony_ci } 281cc290419Sopenharmony_ci 282cc290419Sopenharmony_ci pub fn wrap_connect(socket_fd: i32, addr: &UdsAddr) -> Result<()> { 283cc290419Sopenharmony_ci unsafe { 284cc290419Sopenharmony_ci let (addr_raw, len_raw) = addr.as_raw_general(); 285cc290419Sopenharmony_ci crate::debug!("wrap_connect:len_raw: {:#?}", len_raw); 286cc290419Sopenharmony_ci crate::debug!("wrap_connect:addr_raw: {:#?}", addr_raw.sa_data); 287cc290419Sopenharmony_ci loop { 288cc290419Sopenharmony_ci let ret = connect(socket_fd, addr_raw, len_raw); 289cc290419Sopenharmony_ci crate::debug!("connect ret ++++++---->: {}", ret); 290cc290419Sopenharmony_ci if ret != -1 { 291cc290419Sopenharmony_ci break Ok(()); 292cc290419Sopenharmony_ci } 293cc290419Sopenharmony_ci let err = io::Error::last_os_error(); 294cc290419Sopenharmony_ci if err.kind() != ErrorKind::Interrupted { 295cc290419Sopenharmony_ci break Err(err); 296cc290419Sopenharmony_ci } 297cc290419Sopenharmony_ci } 298cc290419Sopenharmony_ci } 299cc290419Sopenharmony_ci } 300cc290419Sopenharmony_ci 301cc290419Sopenharmony_ci pub fn wrap_recv(socket_fd: i32, buffer: &mut [u8]) -> isize { 302cc290419Sopenharmony_ci let ptr = buffer.as_ptr() as *mut c_void; 303cc290419Sopenharmony_ci unsafe { recv(socket_fd, ptr, buffer.len(), MSG_NOSIGNAL) } 304cc290419Sopenharmony_ci } 305cc290419Sopenharmony_ci 306cc290419Sopenharmony_ci pub fn wrap_read(socket_fd: i32, buffer: &mut [u8]) -> isize { 307cc290419Sopenharmony_ci let ptr = buffer.as_ptr() as *mut c_void; 308cc290419Sopenharmony_ci unsafe { read(socket_fd, ptr, buffer.len()) } 309cc290419Sopenharmony_ci } 310cc290419Sopenharmony_ci 311cc290419Sopenharmony_ci pub fn wrap_write(socket_fd: i32, buffer: &[u8]) -> isize { 312cc290419Sopenharmony_ci let ptr = buffer.as_ptr() as *const c_void; 313cc290419Sopenharmony_ci unsafe { write(socket_fd, ptr, buffer.len()) } 314cc290419Sopenharmony_ci } 315cc290419Sopenharmony_ci 316cc290419Sopenharmony_ci pub fn wrap_send(socket_fd: i32, buffer: &[u8]) -> isize { 317cc290419Sopenharmony_ci let ptr = buffer.as_ptr() as *const c_void; 318cc290419Sopenharmony_ci let flags = MSG_NOSIGNAL | MSG_EOR; 319cc290419Sopenharmony_ci unsafe { send(socket_fd, ptr, buffer.len(), flags) } 320cc290419Sopenharmony_ci } 321cc290419Sopenharmony_ci} 322