16046f775S裕依 use core::{cmp::min, ffi::CStr}; 2cde5492fSlogin 3cde5492fSlogin use alloc::{boxed::Box, sync::Arc}; 4cde5492fSlogin use num_traits::{FromPrimitive, ToPrimitive}; 5cde5492fSlogin use smoltcp::wire; 691e9d4abSLoGin use system_error::SystemError; 7cde5492fSlogin 8cde5492fSlogin use crate::{ 9cde5492fSlogin filesystem::vfs::{ 10cde5492fSlogin file::{File, FileMode}, 11cde5492fSlogin syscall::{IoVec, IoVecs}, 126046f775S裕依 FileType, 13cde5492fSlogin }, 14ab5c8ca4Slogin libs::spinlock::SpinLockGuard, 154fda81ceSLoGin mm::{verify_area, VirtAddr}, 16cde5492fSlogin net::socket::{AddressFamily, SOL_SOCKET}, 171496ba7bSLoGin process::ProcessManager, 1891e9d4abSLoGin syscall::Syscall, 19cde5492fSlogin }; 20cde5492fSlogin 21cde5492fSlogin use super::{ 22d623e902SGnoCiYeH socket::{new_socket, PosixSocketType, Socket, SocketInode}, 234ad52e57S裕依2439 Endpoint, Protocol, ShutdownType, 24cde5492fSlogin }; 25cde5492fSlogin 26c47fe904SLoGin /// Flags for socket, socketpair, accept4 27c47fe904SLoGin const SOCK_CLOEXEC: FileMode = FileMode::O_CLOEXEC; 28c47fe904SLoGin const SOCK_NONBLOCK: FileMode = FileMode::O_NONBLOCK; 29c47fe904SLoGin 30ab5c8ca4Slogin impl Syscall { 31cde5492fSlogin /// @brief sys_socket系统调用的实际执行函数 32cde5492fSlogin /// 33cde5492fSlogin /// @param address_family 地址族 34cde5492fSlogin /// @param socket_type socket类型 35cde5492fSlogin /// @param protocol 传输协议 socket( address_family: usize, socket_type: usize, protocol: usize, ) -> Result<usize, SystemError>36ab5c8ca4Slogin pub fn socket( 37cde5492fSlogin address_family: usize, 38cde5492fSlogin socket_type: usize, 39cde5492fSlogin protocol: usize, 40ab5c8ca4Slogin ) -> Result<usize, SystemError> { 41cde5492fSlogin let address_family = AddressFamily::try_from(address_family as u16)?; 42cde5492fSlogin let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?; 434ad52e57S裕依2439 let protocol = Protocol::from(protocol as u8); 444ad52e57S裕依2439 454ad52e57S裕依2439 let socket = new_socket(address_family, socket_type, protocol)?; 464ad52e57S裕依2439 47cde5492fSlogin let socketinode: Arc<SocketInode> = SocketInode::new(socket); 48cde5492fSlogin let f = File::new(socketinode, FileMode::O_RDWR)?; 49cde5492fSlogin // 把socket添加到当前进程的文件描述符表中 501496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 511496ba7bSLoGin let mut fd_table_guard = binding.write(); 521496ba7bSLoGin let fd = fd_table_guard.alloc_fd(f, None).map(|x| x as usize); 531496ba7bSLoGin drop(fd_table_guard); 54cde5492fSlogin return fd; 55cde5492fSlogin } 56cde5492fSlogin 574ad52e57S裕依2439 /// # sys_socketpair系统调用的实际执行函数 584ad52e57S裕依2439 /// 594ad52e57S裕依2439 /// ## 参数 604ad52e57S裕依2439 /// - `address_family`: 地址族 614ad52e57S裕依2439 /// - `socket_type`: socket类型 624ad52e57S裕依2439 /// - `protocol`: 传输协议 634ad52e57S裕依2439 /// - `fds`: 用于返回文件描述符的数组 socketpair( address_family: usize, socket_type: usize, protocol: usize, fds: &mut [i32], ) -> Result<usize, SystemError>644ad52e57S裕依2439 pub fn socketpair( 654ad52e57S裕依2439 address_family: usize, 664ad52e57S裕依2439 socket_type: usize, 674ad52e57S裕依2439 protocol: usize, 684ad52e57S裕依2439 fds: &mut [i32], 694ad52e57S裕依2439 ) -> Result<usize, SystemError> { 704ad52e57S裕依2439 let address_family = AddressFamily::try_from(address_family as u16)?; 714ad52e57S裕依2439 let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?; 724ad52e57S裕依2439 let protocol = Protocol::from(protocol as u8); 734ad52e57S裕依2439 744ad52e57S裕依2439 let binding = ProcessManager::current_pcb().fd_table(); 754ad52e57S裕依2439 let mut fd_table_guard = binding.write(); 764ad52e57S裕依2439 776046f775S裕依 // 创建一对socket 786046f775S裕依 let inode0 = SocketInode::new(new_socket(address_family, socket_type, protocol)?); 796046f775S裕依 let inode1 = SocketInode::new(new_socket(address_family, socket_type, protocol)?); 804ad52e57S裕依2439 816046f775S裕依 // 进行pair 826046f775S裕依 unsafe { 836046f775S裕依 inode0 846046f775S裕依 .inner_no_preempt() 856046f775S裕依 .connect(Endpoint::Inode(Some(inode1.clone())))?; 866046f775S裕依 inode1 876046f775S裕依 .inner_no_preempt() 886046f775S裕依 .connect(Endpoint::Inode(Some(inode0.clone())))?; 896046f775S裕依 } 906046f775S裕依 916046f775S裕依 fds[0] = fd_table_guard.alloc_fd(File::new(inode0, FileMode::O_RDWR)?, None)?; 926046f775S裕依 fds[1] = fd_table_guard.alloc_fd(File::new(inode1, FileMode::O_RDWR)?, None)?; 934ad52e57S裕依2439 944ad52e57S裕依2439 drop(fd_table_guard); 954ad52e57S裕依2439 Ok(0) 964ad52e57S裕依2439 } 974ad52e57S裕依2439 98cde5492fSlogin /// @brief sys_setsockopt系统调用的实际执行函数 99cde5492fSlogin /// 100cde5492fSlogin /// @param fd 文件描述符 101cde5492fSlogin /// @param level 选项级别 102cde5492fSlogin /// @param optname 选项名称 103cde5492fSlogin /// @param optval 选项值 104cde5492fSlogin /// @param optlen optval缓冲区长度 setsockopt( fd: usize, level: usize, optname: usize, optval: &[u8], ) -> Result<usize, SystemError>105ab5c8ca4Slogin pub fn setsockopt( 106cde5492fSlogin fd: usize, 107cde5492fSlogin level: usize, 108cde5492fSlogin optname: usize, 109ab5c8ca4Slogin optval: &[u8], 110ab5c8ca4Slogin ) -> Result<usize, SystemError> { 1111496ba7bSLoGin let socket_inode: Arc<SocketInode> = ProcessManager::current_pcb() 112cde5492fSlogin .get_socket(fd as i32) 113cde5492fSlogin .ok_or(SystemError::EBADF)?; 114cde5492fSlogin // 获取内层的socket(真正的数据) 115ab5c8ca4Slogin let socket: SpinLockGuard<Box<dyn Socket>> = socket_inode.inner(); 116ab5c8ca4Slogin return socket.setsockopt(level, optname, optval).map(|_| 0); 117cde5492fSlogin } 118cde5492fSlogin 119cde5492fSlogin /// @brief sys_getsockopt系统调用的实际执行函数 120cde5492fSlogin /// 121cde5492fSlogin /// 参考:https://man7.org/linux/man-pages/man2/setsockopt.2.html 122cde5492fSlogin /// 123cde5492fSlogin /// @param fd 文件描述符 124cde5492fSlogin /// @param level 选项级别 125cde5492fSlogin /// @param optname 选项名称 126cde5492fSlogin /// @param optval 返回的选项值 127cde5492fSlogin /// @param optlen 返回的optval缓冲区长度 getsockopt( fd: usize, level: usize, optname: usize, optval: *mut u8, optlen: *mut u32, ) -> Result<usize, SystemError>128ab5c8ca4Slogin pub fn getsockopt( 129cde5492fSlogin fd: usize, 130cde5492fSlogin level: usize, 131cde5492fSlogin optname: usize, 132cde5492fSlogin optval: *mut u8, 133cde5492fSlogin optlen: *mut u32, 134ab5c8ca4Slogin ) -> Result<usize, SystemError> { 135cde5492fSlogin // 获取socket 136cde5492fSlogin let optval = optval as *mut u32; 1371496ba7bSLoGin let binding: Arc<SocketInode> = ProcessManager::current_pcb() 138cde5492fSlogin .get_socket(fd as i32) 139cde5492fSlogin .ok_or(SystemError::EBADF)?; 140cde5492fSlogin let socket = binding.inner(); 141cde5492fSlogin 142cde5492fSlogin if level as u8 == SOL_SOCKET { 143ab5c8ca4Slogin let optname = PosixSocketOption::try_from(optname as i32) 144ab5c8ca4Slogin .map_err(|_| SystemError::ENOPROTOOPT)?; 145cde5492fSlogin match optname { 146cde5492fSlogin PosixSocketOption::SO_SNDBUF => { 147cde5492fSlogin // 返回发送缓冲区大小 148cde5492fSlogin unsafe { 1496046f775S裕依 *optval = socket.metadata().tx_buf_size as u32; 150cde5492fSlogin *optlen = core::mem::size_of::<u32>() as u32; 151cde5492fSlogin } 152cde5492fSlogin return Ok(0); 153cde5492fSlogin } 154cde5492fSlogin PosixSocketOption::SO_RCVBUF => { 155cde5492fSlogin // 返回默认的接收缓冲区大小 156cde5492fSlogin unsafe { 1576046f775S裕依 *optval = socket.metadata().rx_buf_size as u32; 158cde5492fSlogin *optlen = core::mem::size_of::<u32>() as u32; 159cde5492fSlogin } 160cde5492fSlogin return Ok(0); 161cde5492fSlogin } 162cde5492fSlogin _ => { 163cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 164cde5492fSlogin } 165cde5492fSlogin } 166cde5492fSlogin } 167cde5492fSlogin drop(socket); 168cde5492fSlogin 169cde5492fSlogin // To manipulate options at any other level the 170cde5492fSlogin // protocol number of the appropriate protocol controlling the 171cde5492fSlogin // option is supplied. For example, to indicate that an option is 172cde5492fSlogin // to be interpreted by the TCP protocol, level should be set to the 173cde5492fSlogin // protocol number of TCP. 174cde5492fSlogin 175cde5492fSlogin let posix_protocol = 176cde5492fSlogin PosixIpProtocol::try_from(level as u16).map_err(|_| SystemError::ENOPROTOOPT)?; 177cde5492fSlogin if posix_protocol == PosixIpProtocol::TCP { 178cde5492fSlogin let optname = PosixTcpSocketOptions::try_from(optname as i32) 179cde5492fSlogin .map_err(|_| SystemError::ENOPROTOOPT)?; 180cde5492fSlogin match optname { 181cde5492fSlogin PosixTcpSocketOptions::Congestion => return Ok(0), 182cde5492fSlogin _ => { 183cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 184cde5492fSlogin } 185cde5492fSlogin } 186cde5492fSlogin } 187cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 188cde5492fSlogin } 189cde5492fSlogin 190cde5492fSlogin /// @brief sys_connect系统调用的实际执行函数 191cde5492fSlogin /// 192cde5492fSlogin /// @param fd 文件描述符 193cde5492fSlogin /// @param addr SockAddr 194cde5492fSlogin /// @param addrlen 地址长度 195cde5492fSlogin /// 196cde5492fSlogin /// @return 成功返回0,失败返回错误码 connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError>197ab5c8ca4Slogin pub fn connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> { 198cde5492fSlogin let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?; 1991496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 200cde5492fSlogin .get_socket(fd as i32) 201cde5492fSlogin .ok_or(SystemError::EBADF)?; 2022f6f547aSGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 203cde5492fSlogin socket.connect(endpoint)?; 2046046f775S裕依 Ok(0) 205cde5492fSlogin } 206cde5492fSlogin 207cde5492fSlogin /// @brief sys_bind系统调用的实际执行函数 208cde5492fSlogin /// 209cde5492fSlogin /// @param fd 文件描述符 210cde5492fSlogin /// @param addr SockAddr 211cde5492fSlogin /// @param addrlen 地址长度 212cde5492fSlogin /// 213cde5492fSlogin /// @return 成功返回0,失败返回错误码 bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError>214ab5c8ca4Slogin pub fn bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> { 215cde5492fSlogin let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?; 2161496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 217cde5492fSlogin .get_socket(fd as i32) 218cde5492fSlogin .ok_or(SystemError::EBADF)?; 2192f6f547aSGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 220cde5492fSlogin socket.bind(endpoint)?; 2216046f775S裕依 Ok(0) 222cde5492fSlogin } 223cde5492fSlogin 224cde5492fSlogin /// @brief sys_sendto系统调用的实际执行函数 225cde5492fSlogin /// 226cde5492fSlogin /// @param fd 文件描述符 227cde5492fSlogin /// @param buf 发送缓冲区 228cde5492fSlogin /// @param flags 标志 229cde5492fSlogin /// @param addr SockAddr 230cde5492fSlogin /// @param addrlen 地址长度 231cde5492fSlogin /// 232cde5492fSlogin /// @return 成功返回发送的字节数,失败返回错误码 sendto( fd: usize, buf: &[u8], _flags: u32, addr: *const SockAddr, addrlen: usize, ) -> Result<usize, SystemError>233ab5c8ca4Slogin pub fn sendto( 234cde5492fSlogin fd: usize, 235ab5c8ca4Slogin buf: &[u8], 236ab5c8ca4Slogin _flags: u32, 237cde5492fSlogin addr: *const SockAddr, 238cde5492fSlogin addrlen: usize, 239ab5c8ca4Slogin ) -> Result<usize, SystemError> { 240cde5492fSlogin let endpoint = if addr.is_null() { 241cde5492fSlogin None 242cde5492fSlogin } else { 243cde5492fSlogin Some(SockAddr::to_endpoint(addr, addrlen)?) 244cde5492fSlogin }; 245cde5492fSlogin 2461496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 247cde5492fSlogin .get_socket(fd as i32) 248cde5492fSlogin .ok_or(SystemError::EBADF)?; 2492f6f547aSGnoCiYeH let socket = unsafe { socket.inner_no_preempt() }; 250ab5c8ca4Slogin return socket.write(buf, endpoint); 251cde5492fSlogin } 252cde5492fSlogin 253cde5492fSlogin /// @brief sys_recvfrom系统调用的实际执行函数 254cde5492fSlogin /// 255cde5492fSlogin /// @param fd 文件描述符 256cde5492fSlogin /// @param buf 接收缓冲区 257cde5492fSlogin /// @param flags 标志 258cde5492fSlogin /// @param addr SockAddr 259cde5492fSlogin /// @param addrlen 地址长度 260cde5492fSlogin /// 261cde5492fSlogin /// @return 成功返回接收的字节数,失败返回错误码 recvfrom( fd: usize, buf: &mut [u8], _flags: u32, addr: *mut SockAddr, addrlen: *mut u32, ) -> Result<usize, SystemError>262ab5c8ca4Slogin pub fn recvfrom( 263cde5492fSlogin fd: usize, 264ab5c8ca4Slogin buf: &mut [u8], 265ab5c8ca4Slogin _flags: u32, 266cde5492fSlogin addr: *mut SockAddr, 267cde5492fSlogin addrlen: *mut u32, 268ab5c8ca4Slogin ) -> Result<usize, SystemError> { 2691496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 270cde5492fSlogin .get_socket(fd as i32) 271cde5492fSlogin .ok_or(SystemError::EBADF)?; 2726046f775S裕依 let socket = unsafe { socket.inner_no_preempt() }; 273cde5492fSlogin 274cde5492fSlogin let (n, endpoint) = socket.read(buf); 275cde5492fSlogin drop(socket); 276cde5492fSlogin 277cde5492fSlogin let n: usize = n?; 278cde5492fSlogin 279cde5492fSlogin // 如果有地址信息,将地址信息写入用户空间 280cde5492fSlogin if !addr.is_null() { 281cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 282cde5492fSlogin unsafe { 283cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 284cde5492fSlogin } 285cde5492fSlogin } 286ab5c8ca4Slogin return Ok(n); 287cde5492fSlogin } 288cde5492fSlogin 289cde5492fSlogin /// @brief sys_recvmsg系统调用的实际执行函数 290cde5492fSlogin /// 291cde5492fSlogin /// @param fd 文件描述符 292cde5492fSlogin /// @param msg MsgHdr 293ab5c8ca4Slogin /// @param flags 标志,暂时未使用 294cde5492fSlogin /// 295cde5492fSlogin /// @return 成功返回接收的字节数,失败返回错误码 recvmsg(fd: usize, msg: &mut MsgHdr, _flags: u32) -> Result<usize, SystemError>296ab5c8ca4Slogin pub fn recvmsg(fd: usize, msg: &mut MsgHdr, _flags: u32) -> Result<usize, SystemError> { 297cde5492fSlogin // 检查每个缓冲区地址是否合法,生成iovecs 298cde5492fSlogin let mut iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? }; 299cde5492fSlogin 3001496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 301cde5492fSlogin .get_socket(fd as i32) 302cde5492fSlogin .ok_or(SystemError::EBADF)?; 3036046f775S裕依 let socket = unsafe { socket.inner_no_preempt() }; 304cde5492fSlogin 305cde5492fSlogin let mut buf = iovs.new_buf(true); 306cde5492fSlogin // 从socket中读取数据 307cde5492fSlogin let (n, endpoint) = socket.read(&mut buf); 308cde5492fSlogin drop(socket); 309cde5492fSlogin 310cde5492fSlogin let n: usize = n?; 311cde5492fSlogin 312cde5492fSlogin // 将数据写入用户空间的iovecs 313cde5492fSlogin iovs.scatter(&buf[..n]); 314cde5492fSlogin 315cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 316cde5492fSlogin unsafe { 317cde5492fSlogin sockaddr_in.write_to_user(msg.msg_name, &mut msg.msg_namelen)?; 318cde5492fSlogin } 319ab5c8ca4Slogin return Ok(n); 320cde5492fSlogin } 321cde5492fSlogin 322cde5492fSlogin /// @brief sys_listen系统调用的实际执行函数 323cde5492fSlogin /// 324cde5492fSlogin /// @param fd 文件描述符 325ab5c8ca4Slogin /// @param backlog 队列最大连接数 326cde5492fSlogin /// 327cde5492fSlogin /// @return 成功返回0,失败返回错误码 listen(fd: usize, backlog: usize) -> Result<usize, SystemError>328ab5c8ca4Slogin pub fn listen(fd: usize, backlog: usize) -> Result<usize, SystemError> { 3291496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 330cde5492fSlogin .get_socket(fd as i32) 331cde5492fSlogin .ok_or(SystemError::EBADF)?; 3322f6f547aSGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 333cde5492fSlogin socket.listen(backlog)?; 334cde5492fSlogin return Ok(0); 335cde5492fSlogin } 336cde5492fSlogin 337cde5492fSlogin /// @brief sys_shutdown系统调用的实际执行函数 338cde5492fSlogin /// 339cde5492fSlogin /// @param fd 文件描述符 340cde5492fSlogin /// @param how 关闭方式 341cde5492fSlogin /// 342cde5492fSlogin /// @return 成功返回0,失败返回错误码 shutdown(fd: usize, how: usize) -> Result<usize, SystemError>343ab5c8ca4Slogin pub fn shutdown(fd: usize, how: usize) -> Result<usize, SystemError> { 3441496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 345cde5492fSlogin .get_socket(fd as i32) 346cde5492fSlogin .ok_or(SystemError::EBADF)?; 34740609970SGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 348*09836e1bSSamuel Dai socket.shutdown(ShutdownType::from_bits_truncate((how + 1) as u8))?; 349cde5492fSlogin return Ok(0); 350cde5492fSlogin } 351cde5492fSlogin 352cde5492fSlogin /// @brief sys_accept系统调用的实际执行函数 353cde5492fSlogin /// 354cde5492fSlogin /// @param fd 文件描述符 355cde5492fSlogin /// @param addr SockAddr 356cde5492fSlogin /// @param addrlen 地址长度 357cde5492fSlogin /// 358cde5492fSlogin /// @return 成功返回新的文件描述符,失败返回错误码 accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<usize, SystemError>359ab5c8ca4Slogin pub fn accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<usize, SystemError> { 360c47fe904SLoGin return Self::do_accept(fd, addr, addrlen, 0); 361c47fe904SLoGin } 362c47fe904SLoGin 363c47fe904SLoGin /// sys_accept4 - accept a connection on a socket 364c47fe904SLoGin /// 365c47fe904SLoGin /// 366c47fe904SLoGin /// If flags is 0, then accept4() is the same as accept(). The 367c47fe904SLoGin /// following values can be bitwise ORed in flags to obtain different 368c47fe904SLoGin /// behavior: 369c47fe904SLoGin /// 370c47fe904SLoGin /// - SOCK_NONBLOCK 371c47fe904SLoGin /// Set the O_NONBLOCK file status flag on the open file 372c47fe904SLoGin /// description (see open(2)) referred to by the new file 373c47fe904SLoGin /// descriptor. Using this flag saves extra calls to fcntl(2) 374c47fe904SLoGin /// to achieve the same result. 375c47fe904SLoGin /// 376c47fe904SLoGin /// - SOCK_CLOEXEC 377c47fe904SLoGin /// Set the close-on-exec (FD_CLOEXEC) flag on the new file 378c47fe904SLoGin /// descriptor. See the description of the O_CLOEXEC flag in 379c47fe904SLoGin /// open(2) for reasons why this may be useful. accept4( fd: usize, addr: *mut SockAddr, addrlen: *mut u32, mut flags: u32, ) -> Result<usize, SystemError>380c47fe904SLoGin pub fn accept4( 381c47fe904SLoGin fd: usize, 382c47fe904SLoGin addr: *mut SockAddr, 383c47fe904SLoGin addrlen: *mut u32, 384c47fe904SLoGin mut flags: u32, 385c47fe904SLoGin ) -> Result<usize, SystemError> { 386c47fe904SLoGin // 如果flags不合法,返回错误 387c47fe904SLoGin if (flags & (!(SOCK_CLOEXEC | SOCK_NONBLOCK)).bits()) != 0 { 388c47fe904SLoGin return Err(SystemError::EINVAL); 389c47fe904SLoGin } 390c47fe904SLoGin 391c47fe904SLoGin if SOCK_NONBLOCK != FileMode::O_NONBLOCK && ((flags & SOCK_NONBLOCK.bits()) != 0) { 3924ad52e57S裕依2439 flags = (flags & !FileMode::O_NONBLOCK.bits()) | FileMode::O_NONBLOCK.bits(); 393c47fe904SLoGin } 394c47fe904SLoGin 395c47fe904SLoGin return Self::do_accept(fd, addr, addrlen, flags); 396c47fe904SLoGin } 397c47fe904SLoGin do_accept( fd: usize, addr: *mut SockAddr, addrlen: *mut u32, flags: u32, ) -> Result<usize, SystemError>398c47fe904SLoGin fn do_accept( 399c47fe904SLoGin fd: usize, 400c47fe904SLoGin addr: *mut SockAddr, 401c47fe904SLoGin addrlen: *mut u32, 402c47fe904SLoGin flags: u32, 403c47fe904SLoGin ) -> Result<usize, SystemError> { 4041496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 405cde5492fSlogin .get_socket(fd as i32) 406cde5492fSlogin .ok_or(SystemError::EBADF)?; 4072eab6dd7S曾俊 // debug!("accept: socket={:?}", socket); 4082f6f547aSGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 409cde5492fSlogin // 从socket中接收连接 410cde5492fSlogin let (new_socket, remote_endpoint) = socket.accept()?; 411cde5492fSlogin drop(socket); 412cde5492fSlogin 4132eab6dd7S曾俊 // debug!("accept: new_socket={:?}", new_socket); 414cde5492fSlogin // Insert the new socket into the file descriptor vector 415cde5492fSlogin let new_socket: Arc<SocketInode> = SocketInode::new(new_socket); 416c47fe904SLoGin 417c47fe904SLoGin let mut file_mode = FileMode::O_RDWR; 4184ad52e57S裕依2439 if flags & SOCK_NONBLOCK.bits() != 0 { 419c47fe904SLoGin file_mode |= FileMode::O_NONBLOCK; 420c47fe904SLoGin } 4214ad52e57S裕依2439 if flags & SOCK_CLOEXEC.bits() != 0 { 422c47fe904SLoGin file_mode |= FileMode::O_CLOEXEC; 423c47fe904SLoGin } 424c47fe904SLoGin 4251496ba7bSLoGin let new_fd = ProcessManager::current_pcb() 4261496ba7bSLoGin .fd_table() 4271496ba7bSLoGin .write() 428c47fe904SLoGin .alloc_fd(File::new(new_socket, file_mode)?, None)?; 4292eab6dd7S曾俊 // debug!("accept: new_fd={}", new_fd); 430cde5492fSlogin if !addr.is_null() { 4312eab6dd7S曾俊 // debug!("accept: write remote_endpoint to user"); 432cde5492fSlogin // 将对端地址写入用户空间 433cde5492fSlogin let sockaddr_in = SockAddr::from(remote_endpoint); 434cde5492fSlogin unsafe { 435cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 436cde5492fSlogin } 437cde5492fSlogin } 438ab5c8ca4Slogin return Ok(new_fd as usize); 439cde5492fSlogin } 440cde5492fSlogin 441cde5492fSlogin /// @brief sys_getsockname系统调用的实际执行函数 442cde5492fSlogin /// 443cde5492fSlogin /// Returns the current address to which the socket 444cde5492fSlogin /// sockfd is bound, in the buffer pointed to by addr. 445cde5492fSlogin /// 446cde5492fSlogin /// @param fd 文件描述符 447cde5492fSlogin /// @param addr SockAddr 448cde5492fSlogin /// @param addrlen 地址长度 449cde5492fSlogin /// 450cde5492fSlogin /// @return 成功返回0,失败返回错误码 getsockname( fd: usize, addr: *mut SockAddr, addrlen: *mut u32, ) -> Result<usize, SystemError>451ab5c8ca4Slogin pub fn getsockname( 452cde5492fSlogin fd: usize, 453cde5492fSlogin addr: *mut SockAddr, 454cde5492fSlogin addrlen: *mut u32, 455ab5c8ca4Slogin ) -> Result<usize, SystemError> { 456cde5492fSlogin if addr.is_null() { 457cde5492fSlogin return Err(SystemError::EINVAL); 458cde5492fSlogin } 4591496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 460cde5492fSlogin .get_socket(fd as i32) 461cde5492fSlogin .ok_or(SystemError::EBADF)?; 462cde5492fSlogin let socket = socket.inner(); 463cde5492fSlogin let endpoint: Endpoint = socket.endpoint().ok_or(SystemError::EINVAL)?; 464cde5492fSlogin drop(socket); 465cde5492fSlogin 466cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 467cde5492fSlogin unsafe { 468cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 469cde5492fSlogin } 470cde5492fSlogin return Ok(0); 471cde5492fSlogin } 472cde5492fSlogin 473cde5492fSlogin /// @brief sys_getpeername系统调用的实际执行函数 474cde5492fSlogin /// 475cde5492fSlogin /// @param fd 文件描述符 476cde5492fSlogin /// @param addr SockAddr 477cde5492fSlogin /// @param addrlen 地址长度 478cde5492fSlogin /// 479cde5492fSlogin /// @return 成功返回0,失败返回错误码 getpeername( fd: usize, addr: *mut SockAddr, addrlen: *mut u32, ) -> Result<usize, SystemError>480ab5c8ca4Slogin pub fn getpeername( 481cde5492fSlogin fd: usize, 482cde5492fSlogin addr: *mut SockAddr, 483cde5492fSlogin addrlen: *mut u32, 484ab5c8ca4Slogin ) -> Result<usize, SystemError> { 485cde5492fSlogin if addr.is_null() { 486cde5492fSlogin return Err(SystemError::EINVAL); 487cde5492fSlogin } 488cde5492fSlogin 4891496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 490cde5492fSlogin .get_socket(fd as i32) 491cde5492fSlogin .ok_or(SystemError::EBADF)?; 492cde5492fSlogin let socket = socket.inner(); 493cde5492fSlogin let endpoint: Endpoint = socket.peer_endpoint().ok_or(SystemError::EINVAL)?; 494cde5492fSlogin drop(socket); 495cde5492fSlogin 496cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 497cde5492fSlogin unsafe { 498cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 499cde5492fSlogin } 500cde5492fSlogin return Ok(0); 501cde5492fSlogin } 502ab5c8ca4Slogin } 503cde5492fSlogin 504cde5492fSlogin // 参考资料: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html#tag_13_32 505cde5492fSlogin #[repr(C)] 506cde5492fSlogin #[derive(Debug, Clone, Copy)] 507cde5492fSlogin pub struct SockAddrIn { 508cde5492fSlogin pub sin_family: u16, 509cde5492fSlogin pub sin_port: u16, 510cde5492fSlogin pub sin_addr: u32, 511cde5492fSlogin pub sin_zero: [u8; 8], 512cde5492fSlogin } 513cde5492fSlogin 514cde5492fSlogin #[repr(C)] 515cde5492fSlogin #[derive(Debug, Clone, Copy)] 516cde5492fSlogin pub struct SockAddrUn { 517cde5492fSlogin pub sun_family: u16, 518cde5492fSlogin pub sun_path: [u8; 108], 519cde5492fSlogin } 520cde5492fSlogin 521cde5492fSlogin #[repr(C)] 522cde5492fSlogin #[derive(Debug, Clone, Copy)] 523cde5492fSlogin pub struct SockAddrLl { 524cde5492fSlogin pub sll_family: u16, 525cde5492fSlogin pub sll_protocol: u16, 526cde5492fSlogin pub sll_ifindex: u32, 527cde5492fSlogin pub sll_hatype: u16, 528cde5492fSlogin pub sll_pkttype: u8, 529cde5492fSlogin pub sll_halen: u8, 530cde5492fSlogin pub sll_addr: [u8; 8], 531cde5492fSlogin } 532cde5492fSlogin 533cde5492fSlogin #[repr(C)] 534cde5492fSlogin #[derive(Debug, Clone, Copy)] 535cde5492fSlogin pub struct SockAddrNl { 536cde5492fSlogin nl_family: u16, 537cde5492fSlogin nl_pad: u16, 538cde5492fSlogin nl_pid: u32, 539cde5492fSlogin nl_groups: u32, 540cde5492fSlogin } 541cde5492fSlogin 542cde5492fSlogin #[repr(C)] 543cde5492fSlogin #[derive(Debug, Clone, Copy)] 544cde5492fSlogin pub struct SockAddrPlaceholder { 545cde5492fSlogin pub family: u16, 546cde5492fSlogin pub data: [u8; 14], 547cde5492fSlogin } 548cde5492fSlogin 549cde5492fSlogin #[repr(C)] 550cde5492fSlogin #[derive(Clone, Copy)] 551cde5492fSlogin pub union SockAddr { 552cde5492fSlogin pub family: u16, 553cde5492fSlogin pub addr_in: SockAddrIn, 554cde5492fSlogin pub addr_un: SockAddrUn, 555cde5492fSlogin pub addr_ll: SockAddrLl, 556cde5492fSlogin pub addr_nl: SockAddrNl, 557cde5492fSlogin pub addr_ph: SockAddrPlaceholder, 558cde5492fSlogin } 559cde5492fSlogin 560cde5492fSlogin impl SockAddr { 561cde5492fSlogin /// @brief 把用户传入的SockAddr转换为Endpoint结构体 to_endpoint(addr: *const SockAddr, len: usize) -> Result<Endpoint, SystemError>562cde5492fSlogin pub fn to_endpoint(addr: *const SockAddr, len: usize) -> Result<Endpoint, SystemError> { 563cde5492fSlogin verify_area( 5644fda81ceSLoGin VirtAddr::new(addr as usize), 5654fda81ceSLoGin core::mem::size_of::<SockAddr>(), 566cde5492fSlogin ) 5674fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 568cde5492fSlogin 569cde5492fSlogin let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?; 570cde5492fSlogin unsafe { 571cde5492fSlogin match AddressFamily::try_from(addr.family)? { 572cde5492fSlogin AddressFamily::INet => { 5736046f775S裕依 if len < addr.len()? { 5746046f775S裕依 return Err(SystemError::EINVAL); 5756046f775S裕依 } 5766046f775S裕依 577cde5492fSlogin let addr_in: SockAddrIn = addr.addr_in; 578cde5492fSlogin 579cde5492fSlogin let ip: wire::IpAddress = wire::IpAddress::from(wire::Ipv4Address::from_bytes( 580cde5492fSlogin &u32::from_be(addr_in.sin_addr).to_be_bytes()[..], 581cde5492fSlogin )); 582cde5492fSlogin let port = u16::from_be(addr_in.sin_port); 583cde5492fSlogin 584cde5492fSlogin return Ok(Endpoint::Ip(Some(wire::IpEndpoint::new(ip, port)))); 585cde5492fSlogin } 5866046f775S裕依 AddressFamily::Unix => { 5876046f775S裕依 let addr_un: SockAddrUn = addr.addr_un; 5886046f775S裕依 5896046f775S裕依 let path = CStr::from_bytes_until_nul(&addr_un.sun_path) 5906046f775S裕依 .map_err(|_| SystemError::EINVAL)? 5916046f775S裕依 .to_str() 5926046f775S裕依 .map_err(|_| SystemError::EINVAL)?; 5936046f775S裕依 5946046f775S裕依 let fd = Syscall::open(path.as_ptr(), FileMode::O_RDWR.bits(), 0o755, true)?; 5956046f775S裕依 5966046f775S裕依 let binding = ProcessManager::current_pcb().fd_table(); 5976046f775S裕依 let fd_table_guard = binding.read(); 5986046f775S裕依 599dfe53cf0SGnoCiYeH let file = fd_table_guard.get_file_by_fd(fd as i32).unwrap(); 6006046f775S裕依 if file.file_type() != FileType::Socket { 6016046f775S裕依 return Err(SystemError::ENOTSOCK); 6026046f775S裕依 } 6036046f775S裕依 let inode = file.inode(); 6046046f775S裕依 let socketinode = inode.as_any_ref().downcast_ref::<Arc<SocketInode>>(); 6056046f775S裕依 6066046f775S裕依 return Ok(Endpoint::Inode(socketinode.cloned())); 6076046f775S裕依 } 608cde5492fSlogin AddressFamily::Packet => { 609cde5492fSlogin // TODO: support packet socket 610cde5492fSlogin return Err(SystemError::EINVAL); 611cde5492fSlogin } 612cde5492fSlogin AddressFamily::Netlink => { 613cde5492fSlogin // TODO: support netlink socket 614cde5492fSlogin return Err(SystemError::EINVAL); 615cde5492fSlogin } 616cde5492fSlogin _ => { 617cde5492fSlogin return Err(SystemError::EINVAL); 618cde5492fSlogin } 619cde5492fSlogin } 620cde5492fSlogin } 621cde5492fSlogin } 622cde5492fSlogin 623cde5492fSlogin /// @brief 获取地址长度 len(&self) -> Result<usize, SystemError>624cde5492fSlogin pub fn len(&self) -> Result<usize, SystemError> { 625cde5492fSlogin let ret = match AddressFamily::try_from(unsafe { self.family })? { 626cde5492fSlogin AddressFamily::INet => Ok(core::mem::size_of::<SockAddrIn>()), 627cde5492fSlogin AddressFamily::Packet => Ok(core::mem::size_of::<SockAddrLl>()), 628cde5492fSlogin AddressFamily::Netlink => Ok(core::mem::size_of::<SockAddrNl>()), 629cde5492fSlogin AddressFamily::Unix => Err(SystemError::EINVAL), 630cde5492fSlogin _ => Err(SystemError::EINVAL), 631cde5492fSlogin }; 632cde5492fSlogin 633cde5492fSlogin return ret; 634cde5492fSlogin } 635cde5492fSlogin 636cde5492fSlogin /// @brief 把SockAddr的数据写入用户空间 637cde5492fSlogin /// 638cde5492fSlogin /// @param addr 用户空间的SockAddr的地址 639cde5492fSlogin /// @param len 要写入的长度 640cde5492fSlogin /// 641cde5492fSlogin /// @return 成功返回写入的长度,失败返回错误码 write_to_user( &self, addr: *mut SockAddr, addr_len: *mut u32, ) -> Result<usize, SystemError>642cde5492fSlogin pub unsafe fn write_to_user( 643cde5492fSlogin &self, 644cde5492fSlogin addr: *mut SockAddr, 645cde5492fSlogin addr_len: *mut u32, 646cde5492fSlogin ) -> Result<usize, SystemError> { 647cde5492fSlogin // 当用户传入的地址或者长度为空时,直接返回0 648cde5492fSlogin if addr.is_null() || addr_len.is_null() { 649cde5492fSlogin return Ok(0); 650cde5492fSlogin } 6514fda81ceSLoGin 652cde5492fSlogin // 检查用户传入的地址是否合法 6534fda81ceSLoGin verify_area( 6544fda81ceSLoGin VirtAddr::new(addr as usize), 6554fda81ceSLoGin core::mem::size_of::<SockAddr>(), 6564fda81ceSLoGin ) 6574fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 6584fda81ceSLoGin 6594fda81ceSLoGin verify_area( 6604fda81ceSLoGin VirtAddr::new(addr_len as usize), 6614fda81ceSLoGin core::mem::size_of::<u32>(), 6624fda81ceSLoGin ) 6634fda81ceSLoGin .map_err(|_| SystemError::EFAULT)?; 664cde5492fSlogin 665cde5492fSlogin let to_write = min(self.len()?, *addr_len as usize); 666cde5492fSlogin if to_write > 0 { 667cde5492fSlogin let buf = core::slice::from_raw_parts_mut(addr as *mut u8, to_write); 668cde5492fSlogin buf.copy_from_slice(core::slice::from_raw_parts( 669cde5492fSlogin self as *const SockAddr as *const u8, 670cde5492fSlogin to_write, 671cde5492fSlogin )); 672cde5492fSlogin } 673cde5492fSlogin *addr_len = self.len()? as u32; 674cde5492fSlogin return Ok(to_write); 675cde5492fSlogin } 676cde5492fSlogin } 677cde5492fSlogin 678cde5492fSlogin impl From<Endpoint> for SockAddr { from(value: Endpoint) -> Self679cde5492fSlogin fn from(value: Endpoint) -> Self { 680cde5492fSlogin match value { 681cde5492fSlogin Endpoint::Ip(ip_endpoint) => { 682cde5492fSlogin // 未指定地址 683b5b571e0SLoGin if ip_endpoint.is_none() { 684cde5492fSlogin return SockAddr { 685cde5492fSlogin addr_ph: SockAddrPlaceholder { 686cde5492fSlogin family: AddressFamily::Unspecified as u16, 687cde5492fSlogin data: [0; 14], 688cde5492fSlogin }, 689cde5492fSlogin }; 690cde5492fSlogin } 691cde5492fSlogin // 指定了地址 692cde5492fSlogin let ip_endpoint = ip_endpoint.unwrap(); 693cde5492fSlogin match ip_endpoint.addr { 694cde5492fSlogin wire::IpAddress::Ipv4(ipv4_addr) => { 695cde5492fSlogin let addr_in = SockAddrIn { 696cde5492fSlogin sin_family: AddressFamily::INet as u16, 697cde5492fSlogin sin_port: ip_endpoint.port.to_be(), 698cde5492fSlogin sin_addr: u32::from_be_bytes(ipv4_addr.0).to_be(), 699cde5492fSlogin sin_zero: [0; 8], 700cde5492fSlogin }; 701cde5492fSlogin 702cde5492fSlogin return SockAddr { addr_in }; 703cde5492fSlogin } 704cde5492fSlogin _ => { 705cde5492fSlogin unimplemented!("not support ipv6"); 706cde5492fSlogin } 707cde5492fSlogin } 708cde5492fSlogin } 709cde5492fSlogin 710cde5492fSlogin Endpoint::LinkLayer(link_endpoint) => { 711cde5492fSlogin let addr_ll = SockAddrLl { 712cde5492fSlogin sll_family: AddressFamily::Packet as u16, 713cde5492fSlogin sll_protocol: 0, 714cde5492fSlogin sll_ifindex: link_endpoint.interface as u32, 715cde5492fSlogin sll_hatype: 0, 716cde5492fSlogin sll_pkttype: 0, 717cde5492fSlogin sll_halen: 0, 718cde5492fSlogin sll_addr: [0; 8], 719cde5492fSlogin }; 720cde5492fSlogin 721cde5492fSlogin return SockAddr { addr_ll }; 7224ad52e57S裕依2439 } 7236046f775S裕依 7244ad52e57S裕依2439 _ => { 7254ad52e57S裕依2439 // todo: support other endpoint, like Netlink... 7264ad52e57S裕依2439 unimplemented!("not support {value:?}"); 7274ad52e57S裕依2439 } 728cde5492fSlogin } 729cde5492fSlogin } 730cde5492fSlogin } 731cde5492fSlogin 732cde5492fSlogin #[repr(C)] 733cde5492fSlogin #[derive(Debug, Clone, Copy)] 734cde5492fSlogin pub struct MsgHdr { 735cde5492fSlogin /// 指向一个SockAddr结构体的指针 736cde5492fSlogin pub msg_name: *mut SockAddr, 737cde5492fSlogin /// SockAddr结构体的大小 738cde5492fSlogin pub msg_namelen: u32, 739cde5492fSlogin /// scatter/gather array 740cde5492fSlogin pub msg_iov: *mut IoVec, 741cde5492fSlogin /// elements in msg_iov 742cde5492fSlogin pub msg_iovlen: usize, 743cde5492fSlogin /// 辅助数据 744cde5492fSlogin pub msg_control: *mut u8, 745cde5492fSlogin /// 辅助数据长度 746cde5492fSlogin pub msg_controllen: usize, 747cde5492fSlogin /// 接收到的消息的标志 748cde5492fSlogin pub msg_flags: u32, 749cde5492fSlogin } 750cde5492fSlogin 751cde5492fSlogin #[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)] 752cde5492fSlogin pub enum PosixIpProtocol { 753cde5492fSlogin /// Dummy protocol for TCP. 754cde5492fSlogin IP = 0, 755cde5492fSlogin /// Internet Control Message Protocol. 756cde5492fSlogin ICMP = 1, 757cde5492fSlogin /// Internet Group Management Protocol. 758cde5492fSlogin IGMP = 2, 759cde5492fSlogin /// IPIP tunnels (older KA9Q tunnels use 94). 760cde5492fSlogin IPIP = 4, 761cde5492fSlogin /// Transmission Control Protocol. 762cde5492fSlogin TCP = 6, 763cde5492fSlogin /// Exterior Gateway Protocol. 764cde5492fSlogin EGP = 8, 765cde5492fSlogin /// PUP protocol. 766cde5492fSlogin PUP = 12, 767cde5492fSlogin /// User Datagram Protocol. 768cde5492fSlogin UDP = 17, 769cde5492fSlogin /// XNS IDP protocol. 770cde5492fSlogin IDP = 22, 771cde5492fSlogin /// SO Transport Protocol Class 4. 772cde5492fSlogin TP = 29, 773cde5492fSlogin /// Datagram Congestion Control Protocol. 774cde5492fSlogin DCCP = 33, 775cde5492fSlogin /// IPv6-in-IPv4 tunnelling. 776cde5492fSlogin IPv6 = 41, 777cde5492fSlogin /// RSVP Protocol. 778cde5492fSlogin RSVP = 46, 779cde5492fSlogin /// Generic Routing Encapsulation. (Cisco GRE) (rfc 1701, 1702) 780cde5492fSlogin GRE = 47, 781cde5492fSlogin /// Encapsulation Security Payload protocol 782cde5492fSlogin ESP = 50, 783cde5492fSlogin /// Authentication Header protocol 784cde5492fSlogin AH = 51, 785cde5492fSlogin /// Multicast Transport Protocol. 786cde5492fSlogin MTP = 92, 787cde5492fSlogin /// IP option pseudo header for BEET 788cde5492fSlogin BEETPH = 94, 789cde5492fSlogin /// Encapsulation Header. 790cde5492fSlogin ENCAP = 98, 791cde5492fSlogin /// Protocol Independent Multicast. 792cde5492fSlogin PIM = 103, 793cde5492fSlogin /// Compression Header Protocol. 794cde5492fSlogin COMP = 108, 795cde5492fSlogin /// Stream Control Transport Protocol 796cde5492fSlogin SCTP = 132, 797cde5492fSlogin /// UDP-Lite protocol (RFC 3828) 798cde5492fSlogin UDPLITE = 136, 799cde5492fSlogin /// MPLS in IP (RFC 4023) 800cde5492fSlogin MPLSINIP = 137, 801cde5492fSlogin /// Ethernet-within-IPv6 Encapsulation 802cde5492fSlogin ETHERNET = 143, 803cde5492fSlogin /// Raw IP packets 804cde5492fSlogin RAW = 255, 805cde5492fSlogin /// Multipath TCP connection 806cde5492fSlogin MPTCP = 262, 807cde5492fSlogin } 808cde5492fSlogin 809cde5492fSlogin impl TryFrom<u16> for PosixIpProtocol { 810cde5492fSlogin type Error = SystemError; 811cde5492fSlogin try_from(value: u16) -> Result<Self, Self::Error>812cde5492fSlogin fn try_from(value: u16) -> Result<Self, Self::Error> { 813cde5492fSlogin match <Self as FromPrimitive>::from_u16(value) { 814cde5492fSlogin Some(p) => Ok(p), 815cde5492fSlogin None => Err(SystemError::EPROTONOSUPPORT), 816cde5492fSlogin } 817cde5492fSlogin } 818cde5492fSlogin } 819cde5492fSlogin 820b5b571e0SLoGin impl From<PosixIpProtocol> for u16 { from(value: PosixIpProtocol) -> Self821b5b571e0SLoGin fn from(value: PosixIpProtocol) -> Self { 822b5b571e0SLoGin <PosixIpProtocol as ToPrimitive>::to_u16(&value).unwrap() 823cde5492fSlogin } 824cde5492fSlogin } 825cde5492fSlogin 826cde5492fSlogin #[allow(non_camel_case_types)] 827cde5492fSlogin #[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)] 828cde5492fSlogin pub enum PosixSocketOption { 829cde5492fSlogin SO_DEBUG = 1, 830cde5492fSlogin SO_REUSEADDR = 2, 831cde5492fSlogin SO_TYPE = 3, 832cde5492fSlogin SO_ERROR = 4, 833cde5492fSlogin SO_DONTROUTE = 5, 834cde5492fSlogin SO_BROADCAST = 6, 835cde5492fSlogin SO_SNDBUF = 7, 836cde5492fSlogin SO_RCVBUF = 8, 837cde5492fSlogin SO_SNDBUFFORCE = 32, 838cde5492fSlogin SO_RCVBUFFORCE = 33, 839cde5492fSlogin SO_KEEPALIVE = 9, 840cde5492fSlogin SO_OOBINLINE = 10, 841cde5492fSlogin SO_NO_CHECK = 11, 842cde5492fSlogin SO_PRIORITY = 12, 843cde5492fSlogin SO_LINGER = 13, 844cde5492fSlogin SO_BSDCOMPAT = 14, 845cde5492fSlogin SO_REUSEPORT = 15, 846cde5492fSlogin SO_PASSCRED = 16, 847cde5492fSlogin SO_PEERCRED = 17, 848cde5492fSlogin SO_RCVLOWAT = 18, 849cde5492fSlogin SO_SNDLOWAT = 19, 850cde5492fSlogin SO_RCVTIMEO_OLD = 20, 851cde5492fSlogin SO_SNDTIMEO_OLD = 21, 852cde5492fSlogin 853cde5492fSlogin SO_SECURITY_AUTHENTICATION = 22, 854cde5492fSlogin SO_SECURITY_ENCRYPTION_TRANSPORT = 23, 855cde5492fSlogin SO_SECURITY_ENCRYPTION_NETWORK = 24, 856cde5492fSlogin 857cde5492fSlogin SO_BINDTODEVICE = 25, 858cde5492fSlogin 859cde5492fSlogin /// 与SO_GET_FILTER相同 860cde5492fSlogin SO_ATTACH_FILTER = 26, 861cde5492fSlogin SO_DETACH_FILTER = 27, 862cde5492fSlogin 863cde5492fSlogin SO_PEERNAME = 28, 864cde5492fSlogin 865cde5492fSlogin SO_ACCEPTCONN = 30, 866cde5492fSlogin 867cde5492fSlogin SO_PEERSEC = 31, 868cde5492fSlogin SO_PASSSEC = 34, 869cde5492fSlogin 870cde5492fSlogin SO_MARK = 36, 871cde5492fSlogin 872cde5492fSlogin SO_PROTOCOL = 38, 873cde5492fSlogin SO_DOMAIN = 39, 874cde5492fSlogin 875cde5492fSlogin SO_RXQ_OVFL = 40, 876cde5492fSlogin 877cde5492fSlogin /// 与SCM_WIFI_STATUS相同 878cde5492fSlogin SO_WIFI_STATUS = 41, 879cde5492fSlogin SO_PEEK_OFF = 42, 880cde5492fSlogin 881cde5492fSlogin /* Instruct lower device to use last 4-bytes of skb data as FCS */ 882cde5492fSlogin SO_NOFCS = 43, 883cde5492fSlogin 884cde5492fSlogin SO_LOCK_FILTER = 44, 885cde5492fSlogin SO_SELECT_ERR_QUEUE = 45, 886cde5492fSlogin SO_BUSY_POLL = 46, 887cde5492fSlogin SO_MAX_PACING_RATE = 47, 888cde5492fSlogin SO_BPF_EXTENSIONS = 48, 889cde5492fSlogin SO_INCOMING_CPU = 49, 890cde5492fSlogin SO_ATTACH_BPF = 50, 891cde5492fSlogin // SO_DETACH_BPF = SO_DETACH_FILTER, 892cde5492fSlogin SO_ATTACH_REUSEPORT_CBPF = 51, 893cde5492fSlogin SO_ATTACH_REUSEPORT_EBPF = 52, 894cde5492fSlogin 895cde5492fSlogin SO_CNX_ADVICE = 53, 896cde5492fSlogin SCM_TIMESTAMPING_OPT_STATS = 54, 897cde5492fSlogin SO_MEMINFO = 55, 898cde5492fSlogin SO_INCOMING_NAPI_ID = 56, 899cde5492fSlogin SO_COOKIE = 57, 900cde5492fSlogin SCM_TIMESTAMPING_PKTINFO = 58, 901cde5492fSlogin SO_PEERGROUPS = 59, 902cde5492fSlogin SO_ZEROCOPY = 60, 903cde5492fSlogin /// 与SCM_TXTIME相同 904cde5492fSlogin SO_TXTIME = 61, 905cde5492fSlogin 906cde5492fSlogin SO_BINDTOIFINDEX = 62, 907cde5492fSlogin 908cde5492fSlogin SO_TIMESTAMP_OLD = 29, 909cde5492fSlogin SO_TIMESTAMPNS_OLD = 35, 910cde5492fSlogin SO_TIMESTAMPING_OLD = 37, 911cde5492fSlogin SO_TIMESTAMP_NEW = 63, 912cde5492fSlogin SO_TIMESTAMPNS_NEW = 64, 913cde5492fSlogin SO_TIMESTAMPING_NEW = 65, 914cde5492fSlogin 915cde5492fSlogin SO_RCVTIMEO_NEW = 66, 916cde5492fSlogin SO_SNDTIMEO_NEW = 67, 917cde5492fSlogin 918cde5492fSlogin SO_DETACH_REUSEPORT_BPF = 68, 919cde5492fSlogin 920cde5492fSlogin SO_PREFER_BUSY_POLL = 69, 921cde5492fSlogin SO_BUSY_POLL_BUDGET = 70, 922cde5492fSlogin 923cde5492fSlogin SO_NETNS_COOKIE = 71, 924cde5492fSlogin SO_BUF_LOCK = 72, 925cde5492fSlogin SO_RESERVE_MEM = 73, 926cde5492fSlogin SO_TXREHASH = 74, 927cde5492fSlogin SO_RCVMARK = 75, 928cde5492fSlogin } 929cde5492fSlogin 930cde5492fSlogin impl TryFrom<i32> for PosixSocketOption { 931cde5492fSlogin type Error = SystemError; 932cde5492fSlogin try_from(value: i32) -> Result<Self, Self::Error>933cde5492fSlogin fn try_from(value: i32) -> Result<Self, Self::Error> { 934cde5492fSlogin match <Self as FromPrimitive>::from_i32(value) { 935cde5492fSlogin Some(p) => Ok(p), 936cde5492fSlogin None => Err(SystemError::EINVAL), 937cde5492fSlogin } 938cde5492fSlogin } 939cde5492fSlogin } 940cde5492fSlogin 941b5b571e0SLoGin impl From<PosixSocketOption> for i32 { from(value: PosixSocketOption) -> Self942b5b571e0SLoGin fn from(value: PosixSocketOption) -> Self { 943b5b571e0SLoGin <PosixSocketOption as ToPrimitive>::to_i32(&value).unwrap() 944cde5492fSlogin } 945cde5492fSlogin } 946cde5492fSlogin 947cde5492fSlogin #[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)] 948cde5492fSlogin pub enum PosixTcpSocketOptions { 949cde5492fSlogin /// Turn off Nagle's algorithm. 950cde5492fSlogin NoDelay = 1, 951cde5492fSlogin /// Limit MSS. 952cde5492fSlogin MaxSegment = 2, 953cde5492fSlogin /// Never send partially complete segments. 954cde5492fSlogin Cork = 3, 955cde5492fSlogin /// Start keeplives after this period. 956cde5492fSlogin KeepIdle = 4, 957cde5492fSlogin /// Interval between keepalives. 958cde5492fSlogin KeepIntvl = 5, 959cde5492fSlogin /// Number of keepalives before death. 960cde5492fSlogin KeepCnt = 6, 961cde5492fSlogin /// Number of SYN retransmits. 962cde5492fSlogin Syncnt = 7, 963cde5492fSlogin /// Lifetime for orphaned FIN-WAIT-2 state. 964cde5492fSlogin Linger2 = 8, 965cde5492fSlogin /// Wake up listener only when data arrive. 966cde5492fSlogin DeferAccept = 9, 967cde5492fSlogin /// Bound advertised window 968cde5492fSlogin WindowClamp = 10, 969cde5492fSlogin /// Information about this connection. 970cde5492fSlogin Info = 11, 971cde5492fSlogin /// Block/reenable quick acks. 972cde5492fSlogin QuickAck = 12, 973cde5492fSlogin /// Congestion control algorithm. 974cde5492fSlogin Congestion = 13, 975cde5492fSlogin /// TCP MD5 Signature (RFC2385). 976cde5492fSlogin Md5Sig = 14, 977cde5492fSlogin /// Use linear timeouts for thin streams 978cde5492fSlogin ThinLinearTimeouts = 16, 979cde5492fSlogin /// Fast retrans. after 1 dupack. 980cde5492fSlogin ThinDupack = 17, 981cde5492fSlogin /// How long for loss retry before timeout. 982cde5492fSlogin UserTimeout = 18, 983cde5492fSlogin /// TCP sock is under repair right now. 984cde5492fSlogin Repair = 19, 985cde5492fSlogin RepairQueue = 20, 986cde5492fSlogin QueueSeq = 21, 987cde5492fSlogin RepairOptions = 22, 988cde5492fSlogin /// Enable FastOpen on listeners 989cde5492fSlogin FastOpen = 23, 990cde5492fSlogin Timestamp = 24, 991cde5492fSlogin /// Limit number of unsent bytes in write queue. 992cde5492fSlogin NotSentLowat = 25, 993cde5492fSlogin /// Get Congestion Control (optional) info. 994cde5492fSlogin CCInfo = 26, 995cde5492fSlogin /// Record SYN headers for new connections. 996cde5492fSlogin SaveSyn = 27, 997cde5492fSlogin /// Get SYN headers recorded for connection. 998cde5492fSlogin SavedSyn = 28, 999cde5492fSlogin /// Get/set window parameters. 1000cde5492fSlogin RepairWindow = 29, 1001cde5492fSlogin /// Attempt FastOpen with connect. 1002cde5492fSlogin FastOpenConnect = 30, 1003cde5492fSlogin /// Attach a ULP to a TCP connection. 1004cde5492fSlogin ULP = 31, 1005cde5492fSlogin /// TCP MD5 Signature with extensions. 1006cde5492fSlogin Md5SigExt = 32, 1007cde5492fSlogin /// Set the key for Fast Open(cookie). 1008cde5492fSlogin FastOpenKey = 33, 1009cde5492fSlogin /// Enable TFO without a TFO cookie. 1010cde5492fSlogin FastOpenNoCookie = 34, 1011cde5492fSlogin ZeroCopyReceive = 35, 1012cde5492fSlogin /// Notify bytes available to read as a cmsg on read. 1013cde5492fSlogin /// 与TCP_CM_INQ相同 1014cde5492fSlogin INQ = 36, 1015cde5492fSlogin /// delay outgoing packets by XX usec 1016cde5492fSlogin TxDelay = 37, 1017cde5492fSlogin } 1018cde5492fSlogin 1019cde5492fSlogin impl TryFrom<i32> for PosixTcpSocketOptions { 1020cde5492fSlogin type Error = SystemError; 1021cde5492fSlogin try_from(value: i32) -> Result<Self, Self::Error>1022cde5492fSlogin fn try_from(value: i32) -> Result<Self, Self::Error> { 1023cde5492fSlogin match <Self as FromPrimitive>::from_i32(value) { 1024cde5492fSlogin Some(p) => Ok(p), 1025cde5492fSlogin None => Err(SystemError::EINVAL), 1026cde5492fSlogin } 1027cde5492fSlogin } 1028cde5492fSlogin } 1029cde5492fSlogin 1030b5b571e0SLoGin impl From<PosixTcpSocketOptions> for i32 { from(val: PosixTcpSocketOptions) -> Self1031b5b571e0SLoGin fn from(val: PosixTcpSocketOptions) -> Self { 1032b5b571e0SLoGin <PosixTcpSocketOptions as ToPrimitive>::to_i32(&val).unwrap() 1033cde5492fSlogin } 1034cde5492fSlogin } 1035