1cde5492fSlogin use core::cmp::min; 2cde5492fSlogin 3cde5492fSlogin use alloc::{boxed::Box, sync::Arc}; 4cde5492fSlogin use num_traits::{FromPrimitive, ToPrimitive}; 5cde5492fSlogin use smoltcp::wire; 6cde5492fSlogin 7cde5492fSlogin use crate::{ 8cde5492fSlogin filesystem::vfs::{ 9cde5492fSlogin file::{File, FileMode}, 10cde5492fSlogin syscall::{IoVec, IoVecs}, 11cde5492fSlogin }, 12ab5c8ca4Slogin include::bindings::bindings::verify_area, 13ab5c8ca4Slogin libs::spinlock::SpinLockGuard, 14cde5492fSlogin net::socket::{AddressFamily, SOL_SOCKET}, 151496ba7bSLoGin process::ProcessManager, 16ab5c8ca4Slogin syscall::{Syscall, SystemError}, 17cde5492fSlogin }; 18cde5492fSlogin 19cde5492fSlogin use super::{ 20cde5492fSlogin socket::{PosixSocketType, RawSocket, SocketInode, SocketOptions, TcpSocket, UdpSocket}, 21cde5492fSlogin Endpoint, Protocol, ShutdownType, Socket, 22cde5492fSlogin }; 23cde5492fSlogin 24ab5c8ca4Slogin impl Syscall { 25cde5492fSlogin /// @brief sys_socket系统调用的实际执行函数 26cde5492fSlogin /// 27cde5492fSlogin /// @param address_family 地址族 28cde5492fSlogin /// @param socket_type socket类型 29cde5492fSlogin /// @param protocol 传输协议 30ab5c8ca4Slogin pub fn socket( 31cde5492fSlogin address_family: usize, 32cde5492fSlogin socket_type: usize, 33cde5492fSlogin protocol: usize, 34ab5c8ca4Slogin ) -> Result<usize, SystemError> { 35cde5492fSlogin let address_family = AddressFamily::try_from(address_family as u16)?; 36cde5492fSlogin let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?; 37cde5492fSlogin // kdebug!("do_socket: address_family: {address_family:?}, socket_type: {socket_type:?}, protocol: {protocol}"); 38cde5492fSlogin // 根据地址族和socket类型创建socket 39cde5492fSlogin let socket: Box<dyn Socket> = match address_family { 40cde5492fSlogin AddressFamily::Unix | AddressFamily::INet => match socket_type { 41cde5492fSlogin PosixSocketType::Stream => Box::new(TcpSocket::new(SocketOptions::default())), 42cde5492fSlogin PosixSocketType::Datagram => Box::new(UdpSocket::new(SocketOptions::default())), 43cde5492fSlogin PosixSocketType::Raw => Box::new(RawSocket::new( 44cde5492fSlogin Protocol::from(protocol as u8), 45cde5492fSlogin SocketOptions::default(), 46cde5492fSlogin )), 47cde5492fSlogin _ => { 48cde5492fSlogin // kdebug!("do_socket: EINVAL"); 49cde5492fSlogin return Err(SystemError::EINVAL); 50cde5492fSlogin } 51cde5492fSlogin }, 52cde5492fSlogin _ => { 53cde5492fSlogin // kdebug!("do_socket: EAFNOSUPPORT"); 54cde5492fSlogin return Err(SystemError::EAFNOSUPPORT); 55cde5492fSlogin } 56cde5492fSlogin }; 57cde5492fSlogin // kdebug!("do_socket: socket: {socket:?}"); 58cde5492fSlogin let socketinode: Arc<SocketInode> = SocketInode::new(socket); 59cde5492fSlogin let f = File::new(socketinode, FileMode::O_RDWR)?; 60cde5492fSlogin // kdebug!("do_socket: f: {f:?}"); 61cde5492fSlogin // 把socket添加到当前进程的文件描述符表中 621496ba7bSLoGin let binding = ProcessManager::current_pcb().fd_table(); 631496ba7bSLoGin let mut fd_table_guard = binding.write(); 641496ba7bSLoGin 651496ba7bSLoGin let fd = fd_table_guard.alloc_fd(f, None).map(|x| x as usize); 661496ba7bSLoGin drop(fd_table_guard); 67cde5492fSlogin // kdebug!("do_socket: fd: {fd:?}"); 68cde5492fSlogin return fd; 69cde5492fSlogin } 70cde5492fSlogin 71cde5492fSlogin /// @brief sys_setsockopt系统调用的实际执行函数 72cde5492fSlogin /// 73cde5492fSlogin /// @param fd 文件描述符 74cde5492fSlogin /// @param level 选项级别 75cde5492fSlogin /// @param optname 选项名称 76cde5492fSlogin /// @param optval 选项值 77cde5492fSlogin /// @param optlen optval缓冲区长度 78ab5c8ca4Slogin pub fn setsockopt( 79cde5492fSlogin fd: usize, 80cde5492fSlogin level: usize, 81cde5492fSlogin optname: usize, 82ab5c8ca4Slogin optval: &[u8], 83ab5c8ca4Slogin ) -> Result<usize, SystemError> { 841496ba7bSLoGin let socket_inode: Arc<SocketInode> = ProcessManager::current_pcb() 85cde5492fSlogin .get_socket(fd as i32) 86cde5492fSlogin .ok_or(SystemError::EBADF)?; 87cde5492fSlogin // 获取内层的socket(真正的数据) 88ab5c8ca4Slogin let socket: SpinLockGuard<Box<dyn Socket>> = socket_inode.inner(); 89ab5c8ca4Slogin return socket.setsockopt(level, optname, optval).map(|_| 0); 90cde5492fSlogin } 91cde5492fSlogin 92cde5492fSlogin /// @brief sys_getsockopt系统调用的实际执行函数 93cde5492fSlogin /// 94cde5492fSlogin /// 参考:https://man7.org/linux/man-pages/man2/setsockopt.2.html 95cde5492fSlogin /// 96cde5492fSlogin /// @param fd 文件描述符 97cde5492fSlogin /// @param level 选项级别 98cde5492fSlogin /// @param optname 选项名称 99cde5492fSlogin /// @param optval 返回的选项值 100cde5492fSlogin /// @param optlen 返回的optval缓冲区长度 101ab5c8ca4Slogin pub fn getsockopt( 102cde5492fSlogin fd: usize, 103cde5492fSlogin level: usize, 104cde5492fSlogin optname: usize, 105cde5492fSlogin optval: *mut u8, 106cde5492fSlogin optlen: *mut u32, 107ab5c8ca4Slogin ) -> Result<usize, SystemError> { 108cde5492fSlogin // 获取socket 109cde5492fSlogin let optval = optval as *mut u32; 1101496ba7bSLoGin let binding: Arc<SocketInode> = ProcessManager::current_pcb() 111cde5492fSlogin .get_socket(fd as i32) 112cde5492fSlogin .ok_or(SystemError::EBADF)?; 113cde5492fSlogin let socket = binding.inner(); 114cde5492fSlogin 115cde5492fSlogin if level as u8 == SOL_SOCKET { 116ab5c8ca4Slogin let optname = PosixSocketOption::try_from(optname as i32) 117ab5c8ca4Slogin .map_err(|_| SystemError::ENOPROTOOPT)?; 118cde5492fSlogin match optname { 119cde5492fSlogin PosixSocketOption::SO_SNDBUF => { 120cde5492fSlogin // 返回发送缓冲区大小 121cde5492fSlogin unsafe { 122cde5492fSlogin *optval = socket.metadata()?.send_buf_size as u32; 123cde5492fSlogin *optlen = core::mem::size_of::<u32>() as u32; 124cde5492fSlogin } 125cde5492fSlogin return Ok(0); 126cde5492fSlogin } 127cde5492fSlogin PosixSocketOption::SO_RCVBUF => { 128cde5492fSlogin let optval = optval as *mut u32; 129cde5492fSlogin // 返回默认的接收缓冲区大小 130cde5492fSlogin unsafe { 131cde5492fSlogin *optval = socket.metadata()?.recv_buf_size as u32; 132cde5492fSlogin *optlen = core::mem::size_of::<u32>() as u32; 133cde5492fSlogin } 134cde5492fSlogin return Ok(0); 135cde5492fSlogin } 136cde5492fSlogin _ => { 137cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 138cde5492fSlogin } 139cde5492fSlogin } 140cde5492fSlogin } 141cde5492fSlogin drop(socket); 142cde5492fSlogin 143cde5492fSlogin // To manipulate options at any other level the 144cde5492fSlogin // protocol number of the appropriate protocol controlling the 145cde5492fSlogin // option is supplied. For example, to indicate that an option is 146cde5492fSlogin // to be interpreted by the TCP protocol, level should be set to the 147cde5492fSlogin // protocol number of TCP. 148cde5492fSlogin 149cde5492fSlogin let posix_protocol = 150cde5492fSlogin PosixIpProtocol::try_from(level as u16).map_err(|_| SystemError::ENOPROTOOPT)?; 151cde5492fSlogin if posix_protocol == PosixIpProtocol::TCP { 152cde5492fSlogin let optname = PosixTcpSocketOptions::try_from(optname as i32) 153cde5492fSlogin .map_err(|_| SystemError::ENOPROTOOPT)?; 154cde5492fSlogin match optname { 155cde5492fSlogin PosixTcpSocketOptions::Congestion => return Ok(0), 156cde5492fSlogin _ => { 157cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 158cde5492fSlogin } 159cde5492fSlogin } 160cde5492fSlogin } 161cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 162cde5492fSlogin } 163cde5492fSlogin 164cde5492fSlogin /// @brief sys_connect系统调用的实际执行函数 165cde5492fSlogin /// 166cde5492fSlogin /// @param fd 文件描述符 167cde5492fSlogin /// @param addr SockAddr 168cde5492fSlogin /// @param addrlen 地址长度 169cde5492fSlogin /// 170cde5492fSlogin /// @return 成功返回0,失败返回错误码 171ab5c8ca4Slogin pub fn connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> { 172cde5492fSlogin let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?; 1731496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 174cde5492fSlogin .get_socket(fd as i32) 175cde5492fSlogin .ok_or(SystemError::EBADF)?; 176*2f6f547aSGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 177cde5492fSlogin // kdebug!("connect to {:?}...", endpoint); 178cde5492fSlogin socket.connect(endpoint)?; 179cde5492fSlogin return Ok(0); 180cde5492fSlogin } 181cde5492fSlogin 182cde5492fSlogin /// @brief sys_bind系统调用的实际执行函数 183cde5492fSlogin /// 184cde5492fSlogin /// @param fd 文件描述符 185cde5492fSlogin /// @param addr SockAddr 186cde5492fSlogin /// @param addrlen 地址长度 187cde5492fSlogin /// 188cde5492fSlogin /// @return 成功返回0,失败返回错误码 189ab5c8ca4Slogin pub fn bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> { 190cde5492fSlogin let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?; 1911496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 192cde5492fSlogin .get_socket(fd as i32) 193cde5492fSlogin .ok_or(SystemError::EBADF)?; 194*2f6f547aSGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 195cde5492fSlogin socket.bind(endpoint)?; 196cde5492fSlogin return Ok(0); 197cde5492fSlogin } 198cde5492fSlogin 199cde5492fSlogin /// @brief sys_sendto系统调用的实际执行函数 200cde5492fSlogin /// 201cde5492fSlogin /// @param fd 文件描述符 202cde5492fSlogin /// @param buf 发送缓冲区 203cde5492fSlogin /// @param flags 标志 204cde5492fSlogin /// @param addr SockAddr 205cde5492fSlogin /// @param addrlen 地址长度 206cde5492fSlogin /// 207cde5492fSlogin /// @return 成功返回发送的字节数,失败返回错误码 208ab5c8ca4Slogin pub fn sendto( 209cde5492fSlogin fd: usize, 210ab5c8ca4Slogin buf: &[u8], 211ab5c8ca4Slogin _flags: u32, 212cde5492fSlogin addr: *const SockAddr, 213cde5492fSlogin addrlen: usize, 214ab5c8ca4Slogin ) -> Result<usize, SystemError> { 215cde5492fSlogin let endpoint = if addr.is_null() { 216cde5492fSlogin None 217cde5492fSlogin } else { 218cde5492fSlogin Some(SockAddr::to_endpoint(addr, addrlen)?) 219cde5492fSlogin }; 220cde5492fSlogin 2211496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 222cde5492fSlogin .get_socket(fd as i32) 223cde5492fSlogin .ok_or(SystemError::EBADF)?; 224*2f6f547aSGnoCiYeH let socket = unsafe { socket.inner_no_preempt() }; 225ab5c8ca4Slogin return socket.write(buf, endpoint); 226cde5492fSlogin } 227cde5492fSlogin 228cde5492fSlogin /// @brief sys_recvfrom系统调用的实际执行函数 229cde5492fSlogin /// 230cde5492fSlogin /// @param fd 文件描述符 231cde5492fSlogin /// @param buf 接收缓冲区 232cde5492fSlogin /// @param flags 标志 233cde5492fSlogin /// @param addr SockAddr 234cde5492fSlogin /// @param addrlen 地址长度 235cde5492fSlogin /// 236cde5492fSlogin /// @return 成功返回接收的字节数,失败返回错误码 237ab5c8ca4Slogin pub fn recvfrom( 238cde5492fSlogin fd: usize, 239ab5c8ca4Slogin buf: &mut [u8], 240ab5c8ca4Slogin _flags: u32, 241cde5492fSlogin addr: *mut SockAddr, 242cde5492fSlogin addrlen: *mut u32, 243ab5c8ca4Slogin ) -> Result<usize, SystemError> { 2441496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 245cde5492fSlogin .get_socket(fd as i32) 246cde5492fSlogin .ok_or(SystemError::EBADF)?; 247*2f6f547aSGnoCiYeH let socket = unsafe { socket.inner_no_preempt() }; 248cde5492fSlogin 249cde5492fSlogin let (n, endpoint) = socket.read(buf); 250cde5492fSlogin drop(socket); 251cde5492fSlogin 252cde5492fSlogin let n: usize = n?; 253cde5492fSlogin 254cde5492fSlogin // 如果有地址信息,将地址信息写入用户空间 255cde5492fSlogin if !addr.is_null() { 256cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 257cde5492fSlogin unsafe { 258cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 259cde5492fSlogin } 260cde5492fSlogin } 261ab5c8ca4Slogin return Ok(n); 262cde5492fSlogin } 263cde5492fSlogin 264cde5492fSlogin /// @brief sys_recvmsg系统调用的实际执行函数 265cde5492fSlogin /// 266cde5492fSlogin /// @param fd 文件描述符 267cde5492fSlogin /// @param msg MsgHdr 268ab5c8ca4Slogin /// @param flags 标志,暂时未使用 269cde5492fSlogin /// 270cde5492fSlogin /// @return 成功返回接收的字节数,失败返回错误码 271ab5c8ca4Slogin pub fn recvmsg(fd: usize, msg: &mut MsgHdr, _flags: u32) -> Result<usize, SystemError> { 272cde5492fSlogin // 检查每个缓冲区地址是否合法,生成iovecs 273cde5492fSlogin let mut iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? }; 274cde5492fSlogin 2751496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 276cde5492fSlogin .get_socket(fd as i32) 277cde5492fSlogin .ok_or(SystemError::EBADF)?; 278*2f6f547aSGnoCiYeH let socket = unsafe { socket.inner_no_preempt() }; 279cde5492fSlogin 280cde5492fSlogin let mut buf = iovs.new_buf(true); 281cde5492fSlogin // 从socket中读取数据 282cde5492fSlogin let (n, endpoint) = socket.read(&mut buf); 283cde5492fSlogin drop(socket); 284cde5492fSlogin 285cde5492fSlogin let n: usize = n?; 286cde5492fSlogin 287cde5492fSlogin // 将数据写入用户空间的iovecs 288cde5492fSlogin iovs.scatter(&buf[..n]); 289cde5492fSlogin 290cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 291cde5492fSlogin unsafe { 292cde5492fSlogin sockaddr_in.write_to_user(msg.msg_name, &mut msg.msg_namelen)?; 293cde5492fSlogin } 294ab5c8ca4Slogin return Ok(n); 295cde5492fSlogin } 296cde5492fSlogin 297cde5492fSlogin /// @brief sys_listen系统调用的实际执行函数 298cde5492fSlogin /// 299cde5492fSlogin /// @param fd 文件描述符 300ab5c8ca4Slogin /// @param backlog 队列最大连接数 301cde5492fSlogin /// 302cde5492fSlogin /// @return 成功返回0,失败返回错误码 303ab5c8ca4Slogin pub fn listen(fd: usize, backlog: usize) -> Result<usize, SystemError> { 3041496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 305cde5492fSlogin .get_socket(fd as i32) 306cde5492fSlogin .ok_or(SystemError::EBADF)?; 307*2f6f547aSGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 308cde5492fSlogin socket.listen(backlog)?; 309cde5492fSlogin return Ok(0); 310cde5492fSlogin } 311cde5492fSlogin 312cde5492fSlogin /// @brief sys_shutdown系统调用的实际执行函数 313cde5492fSlogin /// 314cde5492fSlogin /// @param fd 文件描述符 315cde5492fSlogin /// @param how 关闭方式 316cde5492fSlogin /// 317cde5492fSlogin /// @return 成功返回0,失败返回错误码 318ab5c8ca4Slogin pub fn shutdown(fd: usize, how: usize) -> Result<usize, SystemError> { 3191496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 320cde5492fSlogin .get_socket(fd as i32) 321cde5492fSlogin .ok_or(SystemError::EBADF)?; 322*2f6f547aSGnoCiYeH let socket = unsafe { socket.inner_no_preempt() }; 323cde5492fSlogin socket.shutdown(ShutdownType::try_from(how as i32)?)?; 324cde5492fSlogin return Ok(0); 325cde5492fSlogin } 326cde5492fSlogin 327cde5492fSlogin /// @brief sys_accept系统调用的实际执行函数 328cde5492fSlogin /// 329cde5492fSlogin /// @param fd 文件描述符 330cde5492fSlogin /// @param addr SockAddr 331cde5492fSlogin /// @param addrlen 地址长度 332cde5492fSlogin /// 333cde5492fSlogin /// @return 成功返回新的文件描述符,失败返回错误码 334ab5c8ca4Slogin pub fn accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<usize, SystemError> { 3351496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 336cde5492fSlogin .get_socket(fd as i32) 337cde5492fSlogin .ok_or(SystemError::EBADF)?; 338cde5492fSlogin // kdebug!("accept: socket={:?}", socket); 339*2f6f547aSGnoCiYeH let mut socket = unsafe { socket.inner_no_preempt() }; 340cde5492fSlogin // 从socket中接收连接 341cde5492fSlogin let (new_socket, remote_endpoint) = socket.accept()?; 342cde5492fSlogin drop(socket); 343cde5492fSlogin 344cde5492fSlogin // kdebug!("accept: new_socket={:?}", new_socket); 345cde5492fSlogin // Insert the new socket into the file descriptor vector 346cde5492fSlogin let new_socket: Arc<SocketInode> = SocketInode::new(new_socket); 3471496ba7bSLoGin let new_fd = ProcessManager::current_pcb() 3481496ba7bSLoGin .fd_table() 3491496ba7bSLoGin .write() 3501496ba7bSLoGin .alloc_fd(File::new(new_socket, FileMode::O_RDWR)?, None)?; 351cde5492fSlogin // kdebug!("accept: new_fd={}", new_fd); 352cde5492fSlogin if !addr.is_null() { 353cde5492fSlogin // kdebug!("accept: write remote_endpoint to user"); 354cde5492fSlogin // 将对端地址写入用户空间 355cde5492fSlogin let sockaddr_in = SockAddr::from(remote_endpoint); 356cde5492fSlogin unsafe { 357cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 358cde5492fSlogin } 359cde5492fSlogin } 360ab5c8ca4Slogin return Ok(new_fd as usize); 361cde5492fSlogin } 362cde5492fSlogin 363cde5492fSlogin /// @brief sys_getsockname系统调用的实际执行函数 364cde5492fSlogin /// 365cde5492fSlogin /// Returns the current address to which the socket 366cde5492fSlogin /// sockfd is bound, in the buffer pointed to by addr. 367cde5492fSlogin /// 368cde5492fSlogin /// @param fd 文件描述符 369cde5492fSlogin /// @param addr SockAddr 370cde5492fSlogin /// @param addrlen 地址长度 371cde5492fSlogin /// 372cde5492fSlogin /// @return 成功返回0,失败返回错误码 373ab5c8ca4Slogin pub fn getsockname( 374cde5492fSlogin fd: usize, 375cde5492fSlogin addr: *mut SockAddr, 376cde5492fSlogin addrlen: *mut u32, 377ab5c8ca4Slogin ) -> Result<usize, SystemError> { 378cde5492fSlogin if addr.is_null() { 379cde5492fSlogin return Err(SystemError::EINVAL); 380cde5492fSlogin } 3811496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 382cde5492fSlogin .get_socket(fd as i32) 383cde5492fSlogin .ok_or(SystemError::EBADF)?; 384cde5492fSlogin let socket = socket.inner(); 385cde5492fSlogin let endpoint: Endpoint = socket.endpoint().ok_or(SystemError::EINVAL)?; 386cde5492fSlogin drop(socket); 387cde5492fSlogin 388cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 389cde5492fSlogin unsafe { 390cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 391cde5492fSlogin } 392cde5492fSlogin return Ok(0); 393cde5492fSlogin } 394cde5492fSlogin 395cde5492fSlogin /// @brief sys_getpeername系统调用的实际执行函数 396cde5492fSlogin /// 397cde5492fSlogin /// @param fd 文件描述符 398cde5492fSlogin /// @param addr SockAddr 399cde5492fSlogin /// @param addrlen 地址长度 400cde5492fSlogin /// 401cde5492fSlogin /// @return 成功返回0,失败返回错误码 402ab5c8ca4Slogin pub fn getpeername( 403cde5492fSlogin fd: usize, 404cde5492fSlogin addr: *mut SockAddr, 405cde5492fSlogin addrlen: *mut u32, 406ab5c8ca4Slogin ) -> Result<usize, SystemError> { 407cde5492fSlogin if addr.is_null() { 408cde5492fSlogin return Err(SystemError::EINVAL); 409cde5492fSlogin } 410cde5492fSlogin 4111496ba7bSLoGin let socket: Arc<SocketInode> = ProcessManager::current_pcb() 412cde5492fSlogin .get_socket(fd as i32) 413cde5492fSlogin .ok_or(SystemError::EBADF)?; 414cde5492fSlogin let socket = socket.inner(); 415cde5492fSlogin let endpoint: Endpoint = socket.peer_endpoint().ok_or(SystemError::EINVAL)?; 416cde5492fSlogin drop(socket); 417cde5492fSlogin 418cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 419cde5492fSlogin unsafe { 420cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 421cde5492fSlogin } 422cde5492fSlogin return Ok(0); 423cde5492fSlogin } 424ab5c8ca4Slogin } 425cde5492fSlogin 426cde5492fSlogin // 参考资料: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html#tag_13_32 427cde5492fSlogin #[repr(C)] 428cde5492fSlogin #[derive(Debug, Clone, Copy)] 429cde5492fSlogin pub struct SockAddrIn { 430cde5492fSlogin pub sin_family: u16, 431cde5492fSlogin pub sin_port: u16, 432cde5492fSlogin pub sin_addr: u32, 433cde5492fSlogin pub sin_zero: [u8; 8], 434cde5492fSlogin } 435cde5492fSlogin 436cde5492fSlogin #[repr(C)] 437cde5492fSlogin #[derive(Debug, Clone, Copy)] 438cde5492fSlogin pub struct SockAddrUn { 439cde5492fSlogin pub sun_family: u16, 440cde5492fSlogin pub sun_path: [u8; 108], 441cde5492fSlogin } 442cde5492fSlogin 443cde5492fSlogin #[repr(C)] 444cde5492fSlogin #[derive(Debug, Clone, Copy)] 445cde5492fSlogin pub struct SockAddrLl { 446cde5492fSlogin pub sll_family: u16, 447cde5492fSlogin pub sll_protocol: u16, 448cde5492fSlogin pub sll_ifindex: u32, 449cde5492fSlogin pub sll_hatype: u16, 450cde5492fSlogin pub sll_pkttype: u8, 451cde5492fSlogin pub sll_halen: u8, 452cde5492fSlogin pub sll_addr: [u8; 8], 453cde5492fSlogin } 454cde5492fSlogin 455cde5492fSlogin #[repr(C)] 456cde5492fSlogin #[derive(Debug, Clone, Copy)] 457cde5492fSlogin pub struct SockAddrNl { 458cde5492fSlogin nl_family: u16, 459cde5492fSlogin nl_pad: u16, 460cde5492fSlogin nl_pid: u32, 461cde5492fSlogin nl_groups: u32, 462cde5492fSlogin } 463cde5492fSlogin 464cde5492fSlogin #[repr(C)] 465cde5492fSlogin #[derive(Debug, Clone, Copy)] 466cde5492fSlogin pub struct SockAddrPlaceholder { 467cde5492fSlogin pub family: u16, 468cde5492fSlogin pub data: [u8; 14], 469cde5492fSlogin } 470cde5492fSlogin 471cde5492fSlogin #[repr(C)] 472cde5492fSlogin #[derive(Clone, Copy)] 473cde5492fSlogin pub union SockAddr { 474cde5492fSlogin pub family: u16, 475cde5492fSlogin pub addr_in: SockAddrIn, 476cde5492fSlogin pub addr_un: SockAddrUn, 477cde5492fSlogin pub addr_ll: SockAddrLl, 478cde5492fSlogin pub addr_nl: SockAddrNl, 479cde5492fSlogin pub addr_ph: SockAddrPlaceholder, 480cde5492fSlogin } 481cde5492fSlogin 482cde5492fSlogin impl SockAddr { 483cde5492fSlogin /// @brief 把用户传入的SockAddr转换为Endpoint结构体 484cde5492fSlogin pub fn to_endpoint(addr: *const SockAddr, len: usize) -> Result<Endpoint, SystemError> { 485cde5492fSlogin if unsafe { 486cde5492fSlogin verify_area( 487cde5492fSlogin addr as usize as u64, 488cde5492fSlogin core::mem::size_of::<SockAddr>() as u64, 489cde5492fSlogin ) 490cde5492fSlogin } == false 491cde5492fSlogin { 492cde5492fSlogin return Err(SystemError::EFAULT); 493cde5492fSlogin } 494cde5492fSlogin 495cde5492fSlogin let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?; 496cde5492fSlogin if len < addr.len()? { 497cde5492fSlogin return Err(SystemError::EINVAL); 498cde5492fSlogin } 499cde5492fSlogin unsafe { 500cde5492fSlogin match AddressFamily::try_from(addr.family)? { 501cde5492fSlogin AddressFamily::INet => { 502cde5492fSlogin let addr_in: SockAddrIn = addr.addr_in; 503cde5492fSlogin 504cde5492fSlogin let ip: wire::IpAddress = wire::IpAddress::from(wire::Ipv4Address::from_bytes( 505cde5492fSlogin &u32::from_be(addr_in.sin_addr).to_be_bytes()[..], 506cde5492fSlogin )); 507cde5492fSlogin let port = u16::from_be(addr_in.sin_port); 508cde5492fSlogin 509cde5492fSlogin return Ok(Endpoint::Ip(Some(wire::IpEndpoint::new(ip, port)))); 510cde5492fSlogin } 511cde5492fSlogin AddressFamily::Packet => { 512cde5492fSlogin // TODO: support packet socket 513cde5492fSlogin return Err(SystemError::EINVAL); 514cde5492fSlogin } 515cde5492fSlogin AddressFamily::Netlink => { 516cde5492fSlogin // TODO: support netlink socket 517cde5492fSlogin return Err(SystemError::EINVAL); 518cde5492fSlogin } 519cde5492fSlogin AddressFamily::Unix => { 520cde5492fSlogin return Err(SystemError::EINVAL); 521cde5492fSlogin } 522cde5492fSlogin _ => { 523cde5492fSlogin return Err(SystemError::EINVAL); 524cde5492fSlogin } 525cde5492fSlogin } 526cde5492fSlogin } 527cde5492fSlogin } 528cde5492fSlogin 529cde5492fSlogin /// @brief 获取地址长度 530cde5492fSlogin pub fn len(&self) -> Result<usize, SystemError> { 531cde5492fSlogin let ret = match AddressFamily::try_from(unsafe { self.family })? { 532cde5492fSlogin AddressFamily::INet => Ok(core::mem::size_of::<SockAddrIn>()), 533cde5492fSlogin AddressFamily::Packet => Ok(core::mem::size_of::<SockAddrLl>()), 534cde5492fSlogin AddressFamily::Netlink => Ok(core::mem::size_of::<SockAddrNl>()), 535cde5492fSlogin AddressFamily::Unix => Err(SystemError::EINVAL), 536cde5492fSlogin _ => Err(SystemError::EINVAL), 537cde5492fSlogin }; 538cde5492fSlogin 539cde5492fSlogin return ret; 540cde5492fSlogin } 541cde5492fSlogin 542cde5492fSlogin /// @brief 把SockAddr的数据写入用户空间 543cde5492fSlogin /// 544cde5492fSlogin /// @param addr 用户空间的SockAddr的地址 545cde5492fSlogin /// @param len 要写入的长度 546cde5492fSlogin /// 547cde5492fSlogin /// @return 成功返回写入的长度,失败返回错误码 548cde5492fSlogin pub unsafe fn write_to_user( 549cde5492fSlogin &self, 550cde5492fSlogin addr: *mut SockAddr, 551cde5492fSlogin addr_len: *mut u32, 552cde5492fSlogin ) -> Result<usize, SystemError> { 553cde5492fSlogin // 当用户传入的地址或者长度为空时,直接返回0 554cde5492fSlogin if addr.is_null() || addr_len.is_null() { 555cde5492fSlogin return Ok(0); 556cde5492fSlogin } 557cde5492fSlogin // 检查用户传入的地址是否合法 558cde5492fSlogin if !verify_area( 559cde5492fSlogin addr as usize as u64, 560cde5492fSlogin core::mem::size_of::<SockAddr>() as u64, 561cde5492fSlogin ) || !verify_area(addr_len as usize as u64, core::mem::size_of::<u32>() as u64) 562cde5492fSlogin { 563cde5492fSlogin return Err(SystemError::EFAULT); 564cde5492fSlogin } 565cde5492fSlogin 566cde5492fSlogin let to_write = min(self.len()?, *addr_len as usize); 567cde5492fSlogin if to_write > 0 { 568cde5492fSlogin let buf = core::slice::from_raw_parts_mut(addr as *mut u8, to_write); 569cde5492fSlogin buf.copy_from_slice(core::slice::from_raw_parts( 570cde5492fSlogin self as *const SockAddr as *const u8, 571cde5492fSlogin to_write, 572cde5492fSlogin )); 573cde5492fSlogin } 574cde5492fSlogin *addr_len = self.len()? as u32; 575cde5492fSlogin return Ok(to_write); 576cde5492fSlogin } 577cde5492fSlogin } 578cde5492fSlogin 579cde5492fSlogin impl From<Endpoint> for SockAddr { 580cde5492fSlogin fn from(value: Endpoint) -> Self { 581cde5492fSlogin match value { 582cde5492fSlogin Endpoint::Ip(ip_endpoint) => { 583cde5492fSlogin // 未指定地址 584cde5492fSlogin if let None = ip_endpoint { 585cde5492fSlogin return SockAddr { 586cde5492fSlogin addr_ph: SockAddrPlaceholder { 587cde5492fSlogin family: AddressFamily::Unspecified as u16, 588cde5492fSlogin data: [0; 14], 589cde5492fSlogin }, 590cde5492fSlogin }; 591cde5492fSlogin } 592cde5492fSlogin // 指定了地址 593cde5492fSlogin let ip_endpoint = ip_endpoint.unwrap(); 594cde5492fSlogin match ip_endpoint.addr { 595cde5492fSlogin wire::IpAddress::Ipv4(ipv4_addr) => { 596cde5492fSlogin let addr_in = SockAddrIn { 597cde5492fSlogin sin_family: AddressFamily::INet as u16, 598cde5492fSlogin sin_port: ip_endpoint.port.to_be(), 599cde5492fSlogin sin_addr: u32::from_be_bytes(ipv4_addr.0).to_be(), 600cde5492fSlogin sin_zero: [0; 8], 601cde5492fSlogin }; 602cde5492fSlogin 603cde5492fSlogin return SockAddr { addr_in }; 604cde5492fSlogin } 605cde5492fSlogin _ => { 606cde5492fSlogin unimplemented!("not support ipv6"); 607cde5492fSlogin } 608cde5492fSlogin } 609cde5492fSlogin } 610cde5492fSlogin 611cde5492fSlogin Endpoint::LinkLayer(link_endpoint) => { 612cde5492fSlogin let addr_ll = SockAddrLl { 613cde5492fSlogin sll_family: AddressFamily::Packet as u16, 614cde5492fSlogin sll_protocol: 0, 615cde5492fSlogin sll_ifindex: link_endpoint.interface as u32, 616cde5492fSlogin sll_hatype: 0, 617cde5492fSlogin sll_pkttype: 0, 618cde5492fSlogin sll_halen: 0, 619cde5492fSlogin sll_addr: [0; 8], 620cde5492fSlogin }; 621cde5492fSlogin 622cde5492fSlogin return SockAddr { addr_ll }; 623cde5492fSlogin } // _ => { 624cde5492fSlogin // // todo: support other endpoint, like Netlink... 625cde5492fSlogin // unimplemented!("not support {value:?}"); 626cde5492fSlogin // } 627cde5492fSlogin } 628cde5492fSlogin } 629cde5492fSlogin } 630cde5492fSlogin 631cde5492fSlogin #[repr(C)] 632cde5492fSlogin #[derive(Debug, Clone, Copy)] 633cde5492fSlogin pub struct MsgHdr { 634cde5492fSlogin /// 指向一个SockAddr结构体的指针 635cde5492fSlogin pub msg_name: *mut SockAddr, 636cde5492fSlogin /// SockAddr结构体的大小 637cde5492fSlogin pub msg_namelen: u32, 638cde5492fSlogin /// scatter/gather array 639cde5492fSlogin pub msg_iov: *mut IoVec, 640cde5492fSlogin /// elements in msg_iov 641cde5492fSlogin pub msg_iovlen: usize, 642cde5492fSlogin /// 辅助数据 643cde5492fSlogin pub msg_control: *mut u8, 644cde5492fSlogin /// 辅助数据长度 645cde5492fSlogin pub msg_controllen: usize, 646cde5492fSlogin /// 接收到的消息的标志 647cde5492fSlogin pub msg_flags: u32, 648cde5492fSlogin } 649cde5492fSlogin 650cde5492fSlogin #[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)] 651cde5492fSlogin pub enum PosixIpProtocol { 652cde5492fSlogin /// Dummy protocol for TCP. 653cde5492fSlogin IP = 0, 654cde5492fSlogin /// Internet Control Message Protocol. 655cde5492fSlogin ICMP = 1, 656cde5492fSlogin /// Internet Group Management Protocol. 657cde5492fSlogin IGMP = 2, 658cde5492fSlogin /// IPIP tunnels (older KA9Q tunnels use 94). 659cde5492fSlogin IPIP = 4, 660cde5492fSlogin /// Transmission Control Protocol. 661cde5492fSlogin TCP = 6, 662cde5492fSlogin /// Exterior Gateway Protocol. 663cde5492fSlogin EGP = 8, 664cde5492fSlogin /// PUP protocol. 665cde5492fSlogin PUP = 12, 666cde5492fSlogin /// User Datagram Protocol. 667cde5492fSlogin UDP = 17, 668cde5492fSlogin /// XNS IDP protocol. 669cde5492fSlogin IDP = 22, 670cde5492fSlogin /// SO Transport Protocol Class 4. 671cde5492fSlogin TP = 29, 672cde5492fSlogin /// Datagram Congestion Control Protocol. 673cde5492fSlogin DCCP = 33, 674cde5492fSlogin /// IPv6-in-IPv4 tunnelling. 675cde5492fSlogin IPv6 = 41, 676cde5492fSlogin /// RSVP Protocol. 677cde5492fSlogin RSVP = 46, 678cde5492fSlogin /// Generic Routing Encapsulation. (Cisco GRE) (rfc 1701, 1702) 679cde5492fSlogin GRE = 47, 680cde5492fSlogin /// Encapsulation Security Payload protocol 681cde5492fSlogin ESP = 50, 682cde5492fSlogin /// Authentication Header protocol 683cde5492fSlogin AH = 51, 684cde5492fSlogin /// Multicast Transport Protocol. 685cde5492fSlogin MTP = 92, 686cde5492fSlogin /// IP option pseudo header for BEET 687cde5492fSlogin BEETPH = 94, 688cde5492fSlogin /// Encapsulation Header. 689cde5492fSlogin ENCAP = 98, 690cde5492fSlogin /// Protocol Independent Multicast. 691cde5492fSlogin PIM = 103, 692cde5492fSlogin /// Compression Header Protocol. 693cde5492fSlogin COMP = 108, 694cde5492fSlogin /// Stream Control Transport Protocol 695cde5492fSlogin SCTP = 132, 696cde5492fSlogin /// UDP-Lite protocol (RFC 3828) 697cde5492fSlogin UDPLITE = 136, 698cde5492fSlogin /// MPLS in IP (RFC 4023) 699cde5492fSlogin MPLSINIP = 137, 700cde5492fSlogin /// Ethernet-within-IPv6 Encapsulation 701cde5492fSlogin ETHERNET = 143, 702cde5492fSlogin /// Raw IP packets 703cde5492fSlogin RAW = 255, 704cde5492fSlogin /// Multipath TCP connection 705cde5492fSlogin MPTCP = 262, 706cde5492fSlogin } 707cde5492fSlogin 708cde5492fSlogin impl TryFrom<u16> for PosixIpProtocol { 709cde5492fSlogin type Error = SystemError; 710cde5492fSlogin 711cde5492fSlogin fn try_from(value: u16) -> Result<Self, Self::Error> { 712cde5492fSlogin match <Self as FromPrimitive>::from_u16(value) { 713cde5492fSlogin Some(p) => Ok(p), 714cde5492fSlogin None => Err(SystemError::EPROTONOSUPPORT), 715cde5492fSlogin } 716cde5492fSlogin } 717cde5492fSlogin } 718cde5492fSlogin 719cde5492fSlogin impl Into<u16> for PosixIpProtocol { 720cde5492fSlogin fn into(self) -> u16 { 721cde5492fSlogin <Self as ToPrimitive>::to_u16(&self).unwrap() 722cde5492fSlogin } 723cde5492fSlogin } 724cde5492fSlogin 725cde5492fSlogin #[allow(non_camel_case_types)] 726cde5492fSlogin #[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)] 727cde5492fSlogin pub enum PosixSocketOption { 728cde5492fSlogin SO_DEBUG = 1, 729cde5492fSlogin SO_REUSEADDR = 2, 730cde5492fSlogin SO_TYPE = 3, 731cde5492fSlogin SO_ERROR = 4, 732cde5492fSlogin SO_DONTROUTE = 5, 733cde5492fSlogin SO_BROADCAST = 6, 734cde5492fSlogin SO_SNDBUF = 7, 735cde5492fSlogin SO_RCVBUF = 8, 736cde5492fSlogin SO_SNDBUFFORCE = 32, 737cde5492fSlogin SO_RCVBUFFORCE = 33, 738cde5492fSlogin SO_KEEPALIVE = 9, 739cde5492fSlogin SO_OOBINLINE = 10, 740cde5492fSlogin SO_NO_CHECK = 11, 741cde5492fSlogin SO_PRIORITY = 12, 742cde5492fSlogin SO_LINGER = 13, 743cde5492fSlogin SO_BSDCOMPAT = 14, 744cde5492fSlogin SO_REUSEPORT = 15, 745cde5492fSlogin SO_PASSCRED = 16, 746cde5492fSlogin SO_PEERCRED = 17, 747cde5492fSlogin SO_RCVLOWAT = 18, 748cde5492fSlogin SO_SNDLOWAT = 19, 749cde5492fSlogin SO_RCVTIMEO_OLD = 20, 750cde5492fSlogin SO_SNDTIMEO_OLD = 21, 751cde5492fSlogin 752cde5492fSlogin SO_SECURITY_AUTHENTICATION = 22, 753cde5492fSlogin SO_SECURITY_ENCRYPTION_TRANSPORT = 23, 754cde5492fSlogin SO_SECURITY_ENCRYPTION_NETWORK = 24, 755cde5492fSlogin 756cde5492fSlogin SO_BINDTODEVICE = 25, 757cde5492fSlogin 758cde5492fSlogin /// 与SO_GET_FILTER相同 759cde5492fSlogin SO_ATTACH_FILTER = 26, 760cde5492fSlogin SO_DETACH_FILTER = 27, 761cde5492fSlogin 762cde5492fSlogin SO_PEERNAME = 28, 763cde5492fSlogin 764cde5492fSlogin SO_ACCEPTCONN = 30, 765cde5492fSlogin 766cde5492fSlogin SO_PEERSEC = 31, 767cde5492fSlogin SO_PASSSEC = 34, 768cde5492fSlogin 769cde5492fSlogin SO_MARK = 36, 770cde5492fSlogin 771cde5492fSlogin SO_PROTOCOL = 38, 772cde5492fSlogin SO_DOMAIN = 39, 773cde5492fSlogin 774cde5492fSlogin SO_RXQ_OVFL = 40, 775cde5492fSlogin 776cde5492fSlogin /// 与SCM_WIFI_STATUS相同 777cde5492fSlogin SO_WIFI_STATUS = 41, 778cde5492fSlogin SO_PEEK_OFF = 42, 779cde5492fSlogin 780cde5492fSlogin /* Instruct lower device to use last 4-bytes of skb data as FCS */ 781cde5492fSlogin SO_NOFCS = 43, 782cde5492fSlogin 783cde5492fSlogin SO_LOCK_FILTER = 44, 784cde5492fSlogin SO_SELECT_ERR_QUEUE = 45, 785cde5492fSlogin SO_BUSY_POLL = 46, 786cde5492fSlogin SO_MAX_PACING_RATE = 47, 787cde5492fSlogin SO_BPF_EXTENSIONS = 48, 788cde5492fSlogin SO_INCOMING_CPU = 49, 789cde5492fSlogin SO_ATTACH_BPF = 50, 790cde5492fSlogin // SO_DETACH_BPF = SO_DETACH_FILTER, 791cde5492fSlogin SO_ATTACH_REUSEPORT_CBPF = 51, 792cde5492fSlogin SO_ATTACH_REUSEPORT_EBPF = 52, 793cde5492fSlogin 794cde5492fSlogin SO_CNX_ADVICE = 53, 795cde5492fSlogin SCM_TIMESTAMPING_OPT_STATS = 54, 796cde5492fSlogin SO_MEMINFO = 55, 797cde5492fSlogin SO_INCOMING_NAPI_ID = 56, 798cde5492fSlogin SO_COOKIE = 57, 799cde5492fSlogin SCM_TIMESTAMPING_PKTINFO = 58, 800cde5492fSlogin SO_PEERGROUPS = 59, 801cde5492fSlogin SO_ZEROCOPY = 60, 802cde5492fSlogin /// 与SCM_TXTIME相同 803cde5492fSlogin SO_TXTIME = 61, 804cde5492fSlogin 805cde5492fSlogin SO_BINDTOIFINDEX = 62, 806cde5492fSlogin 807cde5492fSlogin SO_TIMESTAMP_OLD = 29, 808cde5492fSlogin SO_TIMESTAMPNS_OLD = 35, 809cde5492fSlogin SO_TIMESTAMPING_OLD = 37, 810cde5492fSlogin SO_TIMESTAMP_NEW = 63, 811cde5492fSlogin SO_TIMESTAMPNS_NEW = 64, 812cde5492fSlogin SO_TIMESTAMPING_NEW = 65, 813cde5492fSlogin 814cde5492fSlogin SO_RCVTIMEO_NEW = 66, 815cde5492fSlogin SO_SNDTIMEO_NEW = 67, 816cde5492fSlogin 817cde5492fSlogin SO_DETACH_REUSEPORT_BPF = 68, 818cde5492fSlogin 819cde5492fSlogin SO_PREFER_BUSY_POLL = 69, 820cde5492fSlogin SO_BUSY_POLL_BUDGET = 70, 821cde5492fSlogin 822cde5492fSlogin SO_NETNS_COOKIE = 71, 823cde5492fSlogin SO_BUF_LOCK = 72, 824cde5492fSlogin SO_RESERVE_MEM = 73, 825cde5492fSlogin SO_TXREHASH = 74, 826cde5492fSlogin SO_RCVMARK = 75, 827cde5492fSlogin } 828cde5492fSlogin 829cde5492fSlogin impl TryFrom<i32> for PosixSocketOption { 830cde5492fSlogin type Error = SystemError; 831cde5492fSlogin 832cde5492fSlogin fn try_from(value: i32) -> Result<Self, Self::Error> { 833cde5492fSlogin match <Self as FromPrimitive>::from_i32(value) { 834cde5492fSlogin Some(p) => Ok(p), 835cde5492fSlogin None => Err(SystemError::EINVAL), 836cde5492fSlogin } 837cde5492fSlogin } 838cde5492fSlogin } 839cde5492fSlogin 840cde5492fSlogin impl Into<i32> for PosixSocketOption { 841cde5492fSlogin fn into(self) -> i32 { 842cde5492fSlogin <Self as ToPrimitive>::to_i32(&self).unwrap() 843cde5492fSlogin } 844cde5492fSlogin } 845cde5492fSlogin 846cde5492fSlogin #[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)] 847cde5492fSlogin pub enum PosixTcpSocketOptions { 848cde5492fSlogin /// Turn off Nagle's algorithm. 849cde5492fSlogin NoDelay = 1, 850cde5492fSlogin /// Limit MSS. 851cde5492fSlogin MaxSegment = 2, 852cde5492fSlogin /// Never send partially complete segments. 853cde5492fSlogin Cork = 3, 854cde5492fSlogin /// Start keeplives after this period. 855cde5492fSlogin KeepIdle = 4, 856cde5492fSlogin /// Interval between keepalives. 857cde5492fSlogin KeepIntvl = 5, 858cde5492fSlogin /// Number of keepalives before death. 859cde5492fSlogin KeepCnt = 6, 860cde5492fSlogin /// Number of SYN retransmits. 861cde5492fSlogin Syncnt = 7, 862cde5492fSlogin /// Lifetime for orphaned FIN-WAIT-2 state. 863cde5492fSlogin Linger2 = 8, 864cde5492fSlogin /// Wake up listener only when data arrive. 865cde5492fSlogin DeferAccept = 9, 866cde5492fSlogin /// Bound advertised window 867cde5492fSlogin WindowClamp = 10, 868cde5492fSlogin /// Information about this connection. 869cde5492fSlogin Info = 11, 870cde5492fSlogin /// Block/reenable quick acks. 871cde5492fSlogin QuickAck = 12, 872cde5492fSlogin /// Congestion control algorithm. 873cde5492fSlogin Congestion = 13, 874cde5492fSlogin /// TCP MD5 Signature (RFC2385). 875cde5492fSlogin Md5Sig = 14, 876cde5492fSlogin /// Use linear timeouts for thin streams 877cde5492fSlogin ThinLinearTimeouts = 16, 878cde5492fSlogin /// Fast retrans. after 1 dupack. 879cde5492fSlogin ThinDupack = 17, 880cde5492fSlogin /// How long for loss retry before timeout. 881cde5492fSlogin UserTimeout = 18, 882cde5492fSlogin /// TCP sock is under repair right now. 883cde5492fSlogin Repair = 19, 884cde5492fSlogin RepairQueue = 20, 885cde5492fSlogin QueueSeq = 21, 886cde5492fSlogin RepairOptions = 22, 887cde5492fSlogin /// Enable FastOpen on listeners 888cde5492fSlogin FastOpen = 23, 889cde5492fSlogin Timestamp = 24, 890cde5492fSlogin /// Limit number of unsent bytes in write queue. 891cde5492fSlogin NotSentLowat = 25, 892cde5492fSlogin /// Get Congestion Control (optional) info. 893cde5492fSlogin CCInfo = 26, 894cde5492fSlogin /// Record SYN headers for new connections. 895cde5492fSlogin SaveSyn = 27, 896cde5492fSlogin /// Get SYN headers recorded for connection. 897cde5492fSlogin SavedSyn = 28, 898cde5492fSlogin /// Get/set window parameters. 899cde5492fSlogin RepairWindow = 29, 900cde5492fSlogin /// Attempt FastOpen with connect. 901cde5492fSlogin FastOpenConnect = 30, 902cde5492fSlogin /// Attach a ULP to a TCP connection. 903cde5492fSlogin ULP = 31, 904cde5492fSlogin /// TCP MD5 Signature with extensions. 905cde5492fSlogin Md5SigExt = 32, 906cde5492fSlogin /// Set the key for Fast Open(cookie). 907cde5492fSlogin FastOpenKey = 33, 908cde5492fSlogin /// Enable TFO without a TFO cookie. 909cde5492fSlogin FastOpenNoCookie = 34, 910cde5492fSlogin ZeroCopyReceive = 35, 911cde5492fSlogin /// Notify bytes available to read as a cmsg on read. 912cde5492fSlogin /// 与TCP_CM_INQ相同 913cde5492fSlogin INQ = 36, 914cde5492fSlogin /// delay outgoing packets by XX usec 915cde5492fSlogin TxDelay = 37, 916cde5492fSlogin } 917cde5492fSlogin 918cde5492fSlogin impl TryFrom<i32> for PosixTcpSocketOptions { 919cde5492fSlogin type Error = SystemError; 920cde5492fSlogin 921cde5492fSlogin fn try_from(value: i32) -> Result<Self, Self::Error> { 922cde5492fSlogin match <Self as FromPrimitive>::from_i32(value) { 923cde5492fSlogin Some(p) => Ok(p), 924cde5492fSlogin None => Err(SystemError::EINVAL), 925cde5492fSlogin } 926cde5492fSlogin } 927cde5492fSlogin } 928cde5492fSlogin 929cde5492fSlogin impl Into<i32> for PosixTcpSocketOptions { 930cde5492fSlogin fn into(self) -> i32 { 931cde5492fSlogin <Self as ToPrimitive>::to_i32(&self).unwrap() 932cde5492fSlogin } 933cde5492fSlogin } 934