|
|
@@ -1,29 +1,18 @@
|
|
|
-use core::{cmp::min, ffi::CStr};
|
|
|
-
|
|
|
-use alloc::{boxed::Box, sync::Arc};
|
|
|
-use num_traits::{FromPrimitive, ToPrimitive};
|
|
|
-use smoltcp::wire;
|
|
|
use system_error::SystemError;
|
|
|
|
|
|
use crate::{
|
|
|
filesystem::vfs::{
|
|
|
- fcntl::AtFlags,
|
|
|
file::{File, FileMode},
|
|
|
- iov::{IoVec, IoVecs},
|
|
|
- open::do_sys_open,
|
|
|
- syscall::ModeType,
|
|
|
- FileType,
|
|
|
+ iov::IoVecs,
|
|
|
},
|
|
|
- libs::spinlock::SpinLockGuard,
|
|
|
- mm::{verify_area, VirtAddr},
|
|
|
- net::socket::{AddressFamily, SOL_SOCKET},
|
|
|
+ net::socket::{unix::stream::UnixStreamSocket, AddressFamily, PSOCK},
|
|
|
process::ProcessManager,
|
|
|
syscall::Syscall,
|
|
|
};
|
|
|
|
|
|
use super::{
|
|
|
- socket::{new_socket, PosixSocketType, Socket, SocketInode},
|
|
|
- Endpoint, Protocol, ShutdownType,
|
|
|
+ posix::{MsgHdr, PosixArgsSocketType, SockAddr},
|
|
|
+ socket::{self, common::ShutdownBit, endpoint::Endpoint},
|
|
|
};
|
|
|
|
|
|
/// Flags for socket, socketpair, accept4
|
|
|
@@ -41,20 +30,35 @@ impl Syscall {
|
|
|
socket_type: usize,
|
|
|
protocol: usize,
|
|
|
) -> Result<usize, SystemError> {
|
|
|
- let address_family = AddressFamily::try_from(address_family as u16)?;
|
|
|
- let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?;
|
|
|
- let protocol = Protocol::from(protocol as u8);
|
|
|
-
|
|
|
- let socket = new_socket(address_family, socket_type, protocol)?;
|
|
|
-
|
|
|
- let socketinode: Arc<SocketInode> = SocketInode::new(socket);
|
|
|
- let f = File::new(socketinode, FileMode::O_RDWR)?;
|
|
|
+ // 打印收到的参数
|
|
|
+ // log::debug!(
|
|
|
+ // "socket: address_family={:?}, socket_type={:?}, protocol={:?}",
|
|
|
+ // address_family,
|
|
|
+ // socket_type,
|
|
|
+ // protocol
|
|
|
+ // );
|
|
|
+ let address_family = socket::AddressFamily::try_from(address_family as u16)?;
|
|
|
+ let type_arg = PosixArgsSocketType::from_bits_truncate(socket_type as u32);
|
|
|
+ let is_nonblock = type_arg.is_nonblock();
|
|
|
+ let is_close_on_exec = type_arg.is_cloexec();
|
|
|
+ let stype = socket::PSOCK::try_from(type_arg)?;
|
|
|
+ // log::debug!("type_arg {:?} stype {:?}", type_arg, stype);
|
|
|
+
|
|
|
+ let inode = socket::create_socket(
|
|
|
+ address_family,
|
|
|
+ stype,
|
|
|
+ protocol as u32,
|
|
|
+ is_nonblock,
|
|
|
+ is_close_on_exec,
|
|
|
+ )?;
|
|
|
+
|
|
|
+ let file = File::new(inode, FileMode::O_RDWR)?;
|
|
|
// 把socket添加到当前进程的文件描述符表中
|
|
|
- let binding = ProcessManager::current_pcb().fd_table();
|
|
|
- let mut fd_table_guard = binding.write();
|
|
|
- let fd = fd_table_guard.alloc_fd(f, None).map(|x| x as usize);
|
|
|
- drop(fd_table_guard);
|
|
|
- return fd;
|
|
|
+ ProcessManager::current_pcb()
|
|
|
+ .fd_table()
|
|
|
+ .write()
|
|
|
+ .alloc_fd(file, None)
|
|
|
+ .map(|x| x as usize)
|
|
|
}
|
|
|
|
|
|
/// # sys_socketpair系统调用的实际执行函数
|
|
|
@@ -71,28 +75,36 @@ impl Syscall {
|
|
|
fds: &mut [i32],
|
|
|
) -> Result<usize, SystemError> {
|
|
|
let address_family = AddressFamily::try_from(address_family as u16)?;
|
|
|
- let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?;
|
|
|
- let protocol = Protocol::from(protocol as u8);
|
|
|
+ let socket_type = PosixArgsSocketType::from_bits_truncate(socket_type as u32);
|
|
|
+ let stype = socket::PSOCK::try_from(socket_type)?;
|
|
|
|
|
|
let binding = ProcessManager::current_pcb().fd_table();
|
|
|
let mut fd_table_guard = binding.write();
|
|
|
|
|
|
- // 创建一对socket
|
|
|
- let inode0 = SocketInode::new(new_socket(address_family, socket_type, protocol)?);
|
|
|
- let inode1 = SocketInode::new(new_socket(address_family, socket_type, protocol)?);
|
|
|
-
|
|
|
- // 进行pair
|
|
|
- unsafe {
|
|
|
- inode0
|
|
|
- .inner_no_preempt()
|
|
|
- .connect(Endpoint::Inode(Some(inode1.clone())))?;
|
|
|
- inode1
|
|
|
- .inner_no_preempt()
|
|
|
- .connect(Endpoint::Inode(Some(inode0.clone())))?;
|
|
|
+ // check address family, only support AF_UNIX
|
|
|
+ if address_family != AddressFamily::Unix {
|
|
|
+ log::warn!(
|
|
|
+ "only support AF_UNIX, {:?} with protocol {:?} is not supported",
|
|
|
+ address_family,
|
|
|
+ protocol
|
|
|
+ );
|
|
|
+ return Err(SystemError::EAFNOSUPPORT);
|
|
|
}
|
|
|
|
|
|
- fds[0] = fd_table_guard.alloc_fd(File::new(inode0, FileMode::O_RDWR)?, None)?;
|
|
|
- fds[1] = fd_table_guard.alloc_fd(File::new(inode1, FileMode::O_RDWR)?, None)?;
|
|
|
+ let nonblocking = socket_type.contains(PosixArgsSocketType::NONBLOCK);
|
|
|
+
|
|
|
+ let (socket_a, socket_b) = match (address_family, stype) {
|
|
|
+ (AddressFamily::Unix, PSOCK::Stream) => UnixStreamSocket::new_pair(nonblocking, false),
|
|
|
+ (AddressFamily::Unix, PSOCK::SeqPacket) => {
|
|
|
+ UnixStreamSocket::new_pair(nonblocking, true)
|
|
|
+ }
|
|
|
+ _ => {
|
|
|
+ return Err(SystemError::EAFNOSUPPORT);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ fds[0] = fd_table_guard.alloc_fd(File::new(socket_a, FileMode::O_RDWR)?, None)?;
|
|
|
+ fds[1] = fd_table_guard.alloc_fd(File::new(socket_b, FileMode::O_RDWR)?, None)?;
|
|
|
|
|
|
drop(fd_table_guard);
|
|
|
Ok(0)
|
|
|
@@ -111,12 +123,10 @@ impl Syscall {
|
|
|
optname: usize,
|
|
|
optval: &[u8],
|
|
|
) -> Result<usize, SystemError> {
|
|
|
- let socket_inode: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- // 获取内层的socket(真正的数据)
|
|
|
- let socket: SpinLockGuard<Box<dyn Socket>> = socket_inode.inner();
|
|
|
- return socket.setsockopt(level, optname, optval).map(|_| 0);
|
|
|
+ let sol = socket::PSOL::try_from(level as u32)?;
|
|
|
+ let socket = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
+ log::debug!("setsockopt: level = {:?} ", sol);
|
|
|
+ return socket.set_option(sol, optname, optval).map(|_| 0);
|
|
|
}
|
|
|
|
|
|
/// @brief sys_getsockopt系统调用的实际执行函数
|
|
|
@@ -137,27 +147,27 @@ impl Syscall {
|
|
|
) -> Result<usize, SystemError> {
|
|
|
// 获取socket
|
|
|
let optval = optval as *mut u32;
|
|
|
- let binding: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let socket = binding.inner();
|
|
|
+ let socket = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
|
|
|
- if level as u8 == SOL_SOCKET {
|
|
|
- let optname = PosixSocketOption::try_from(optname as i32)
|
|
|
- .map_err(|_| SystemError::ENOPROTOOPT)?;
|
|
|
+ use socket::{PSO, PSOL};
|
|
|
+
|
|
|
+ let level = PSOL::try_from(level as u32)?;
|
|
|
+
|
|
|
+ if matches!(level, PSOL::SOCKET) {
|
|
|
+ let optname = PSO::try_from(optname as u32).map_err(|_| SystemError::ENOPROTOOPT)?;
|
|
|
match optname {
|
|
|
- PosixSocketOption::SO_SNDBUF => {
|
|
|
+ PSO::SNDBUF => {
|
|
|
// 返回发送缓冲区大小
|
|
|
unsafe {
|
|
|
- *optval = socket.metadata().tx_buf_size as u32;
|
|
|
+ *optval = socket.send_buffer_size() as u32;
|
|
|
*optlen = core::mem::size_of::<u32>() as u32;
|
|
|
}
|
|
|
return Ok(0);
|
|
|
}
|
|
|
- PosixSocketOption::SO_RCVBUF => {
|
|
|
+ PSO::RCVBUF => {
|
|
|
// 返回默认的接收缓冲区大小
|
|
|
unsafe {
|
|
|
- *optval = socket.metadata().rx_buf_size as u32;
|
|
|
+ *optval = socket.recv_buffer_size() as u32;
|
|
|
*optlen = core::mem::size_of::<u32>() as u32;
|
|
|
}
|
|
|
return Ok(0);
|
|
|
@@ -167,7 +177,6 @@ impl Syscall {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- drop(socket);
|
|
|
|
|
|
// To manipulate options at any other level the
|
|
|
// protocol number of the appropriate protocol controlling the
|
|
|
@@ -175,13 +184,12 @@ impl Syscall {
|
|
|
// to be interpreted by the TCP protocol, level should be set to the
|
|
|
// protocol number of TCP.
|
|
|
|
|
|
- let posix_protocol =
|
|
|
- PosixIpProtocol::try_from(level as u16).map_err(|_| SystemError::ENOPROTOOPT)?;
|
|
|
- if posix_protocol == PosixIpProtocol::TCP {
|
|
|
- let optname = PosixTcpSocketOptions::try_from(optname as i32)
|
|
|
- .map_err(|_| SystemError::ENOPROTOOPT)?;
|
|
|
+ if matches!(level, PSOL::TCP) {
|
|
|
+ use socket::inet::stream::TcpOption;
|
|
|
+ let optname =
|
|
|
+ TcpOption::try_from(optname as i32).map_err(|_| SystemError::ENOPROTOOPT)?;
|
|
|
match optname {
|
|
|
- PosixTcpSocketOptions::Congestion => return Ok(0),
|
|
|
+ TcpOption::Congestion => return Ok(0),
|
|
|
_ => {
|
|
|
return Err(SystemError::ENOPROTOOPT);
|
|
|
}
|
|
|
@@ -197,12 +205,9 @@ impl Syscall {
|
|
|
/// @param addrlen 地址长度
|
|
|
///
|
|
|
/// @return 成功返回0,失败返回错误码
|
|
|
- pub fn connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> {
|
|
|
+ pub fn connect(fd: usize, addr: *const SockAddr, addrlen: u32) -> Result<usize, SystemError> {
|
|
|
let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let mut socket = unsafe { socket.inner_no_preempt() };
|
|
|
+ let socket = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
socket.connect(endpoint)?;
|
|
|
Ok(0)
|
|
|
}
|
|
|
@@ -214,12 +219,17 @@ impl Syscall {
|
|
|
/// @param addrlen 地址长度
|
|
|
///
|
|
|
/// @return 成功返回0,失败返回错误码
|
|
|
- pub fn bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> {
|
|
|
+ pub fn bind(fd: usize, addr: *const SockAddr, addrlen: u32) -> Result<usize, SystemError> {
|
|
|
+ // 打印收到的参数
|
|
|
+ // log::debug!(
|
|
|
+ // "bind: fd={:?}, family={:?}, addrlen={:?}",
|
|
|
+ // fd,
|
|
|
+ // (unsafe { addr.as_ref().unwrap().family }),
|
|
|
+ // addrlen
|
|
|
+ // );
|
|
|
let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let mut socket = unsafe { socket.inner_no_preempt() };
|
|
|
+ let socket = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
+ // log::debug!("bind: socket={:?}", socket);
|
|
|
socket.bind(endpoint)?;
|
|
|
Ok(0)
|
|
|
}
|
|
|
@@ -236,9 +246,9 @@ impl Syscall {
|
|
|
pub fn sendto(
|
|
|
fd: usize,
|
|
|
buf: &[u8],
|
|
|
- _flags: u32,
|
|
|
+ flags: u32,
|
|
|
addr: *const SockAddr,
|
|
|
- addrlen: usize,
|
|
|
+ addrlen: u32,
|
|
|
) -> Result<usize, SystemError> {
|
|
|
let endpoint = if addr.is_null() {
|
|
|
None
|
|
|
@@ -246,11 +256,15 @@ impl Syscall {
|
|
|
Some(SockAddr::to_endpoint(addr, addrlen)?)
|
|
|
};
|
|
|
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let socket = unsafe { socket.inner_no_preempt() };
|
|
|
- return socket.write(buf, endpoint);
|
|
|
+ let flags = socket::PMSG::from_bits_truncate(flags);
|
|
|
+
|
|
|
+ let socket = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
+
|
|
|
+ if let Some(endpoint) = endpoint {
|
|
|
+ return socket.send_to(buf, flags, endpoint);
|
|
|
+ } else {
|
|
|
+ return socket.send(buf, flags);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// @brief sys_recvfrom系统调用的实际执行函数
|
|
|
@@ -265,28 +279,33 @@ impl Syscall {
|
|
|
pub fn recvfrom(
|
|
|
fd: usize,
|
|
|
buf: &mut [u8],
|
|
|
- _flags: u32,
|
|
|
+ flags: u32,
|
|
|
addr: *mut SockAddr,
|
|
|
- addrlen: *mut u32,
|
|
|
+ addr_len: *mut u32,
|
|
|
) -> Result<usize, SystemError> {
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let socket = unsafe { socket.inner_no_preempt() };
|
|
|
+ let socket = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
|
|
|
- let (n, endpoint) = socket.read(buf);
|
|
|
- drop(socket);
|
|
|
+ let flags = socket::PMSG::from_bits_truncate(flags);
|
|
|
|
|
|
- let n: usize = n?;
|
|
|
-
|
|
|
- // 如果有地址信息,将地址信息写入用户空间
|
|
|
- if !addr.is_null() {
|
|
|
- let sockaddr_in = SockAddr::from(endpoint);
|
|
|
- unsafe {
|
|
|
- sockaddr_in.write_to_user(addr, addrlen)?;
|
|
|
- }
|
|
|
+ if addr.is_null() {
|
|
|
+ let (n, _) = socket.recv_from(buf, flags, None)?;
|
|
|
+ return Ok(n);
|
|
|
}
|
|
|
- return Ok(n);
|
|
|
+
|
|
|
+ // address is not null
|
|
|
+ let address = unsafe { addr.as_ref() }.ok_or(SystemError::EINVAL)?;
|
|
|
+
|
|
|
+ if unsafe { address.is_empty() } {
|
|
|
+ let (recv_len, endpoint) = socket.recv_from(buf, flags, None)?;
|
|
|
+ endpoint.write_to_user(addr, addr_len)?;
|
|
|
+ return Ok(recv_len);
|
|
|
+ } else {
|
|
|
+ // 从socket中读取数据
|
|
|
+ let addr_len = *unsafe { addr_len.as_ref() }.ok_or(SystemError::EINVAL)?;
|
|
|
+ let address = SockAddr::to_endpoint(addr, addr_len)?;
|
|
|
+ let (recv_len, _) = socket.recv_from(buf, flags, Some(address))?;
|
|
|
+ return Ok(recv_len);
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
/// @brief sys_recvmsg系统调用的实际执行函数
|
|
|
@@ -296,30 +315,26 @@ impl Syscall {
|
|
|
/// @param flags 标志,暂时未使用
|
|
|
///
|
|
|
/// @return 成功返回接收的字节数,失败返回错误码
|
|
|
- pub fn recvmsg(fd: usize, msg: &mut MsgHdr, _flags: u32) -> Result<usize, SystemError> {
|
|
|
+ pub fn recvmsg(fd: usize, msg: &mut MsgHdr, flags: u32) -> Result<usize, SystemError> {
|
|
|
// 检查每个缓冲区地址是否合法,生成iovecs
|
|
|
let iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? };
|
|
|
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let socket = unsafe { socket.inner_no_preempt() };
|
|
|
+ let (buf, recv_size) = {
|
|
|
+ let socket = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
|
|
|
- let mut buf = iovs.new_buf(true);
|
|
|
- // 从socket中读取数据
|
|
|
- let (n, endpoint) = socket.read(&mut buf);
|
|
|
- drop(socket);
|
|
|
+ let flags = socket::PMSG::from_bits_truncate(flags);
|
|
|
|
|
|
- let n: usize = n?;
|
|
|
+ let mut buf = iovs.new_buf(true);
|
|
|
+ // 从socket中读取数据
|
|
|
+ let recv_size = socket.recv(&mut buf, flags)?;
|
|
|
+
|
|
|
+ (buf, recv_size)
|
|
|
+ };
|
|
|
|
|
|
// 将数据写入用户空间的iovecs
|
|
|
- iovs.scatter(&buf[..n]);
|
|
|
+ iovs.scatter(&buf[..recv_size]);
|
|
|
|
|
|
- let sockaddr_in = SockAddr::from(endpoint);
|
|
|
- unsafe {
|
|
|
- sockaddr_in.write_to_user(msg.msg_name, &mut msg.msg_namelen)?;
|
|
|
- }
|
|
|
- return Ok(n);
|
|
|
+ return Ok(recv_size);
|
|
|
}
|
|
|
|
|
|
/// @brief sys_listen系统调用的实际执行函数
|
|
|
@@ -329,12 +344,8 @@ impl Syscall {
|
|
|
///
|
|
|
/// @return 成功返回0,失败返回错误码
|
|
|
pub fn listen(fd: usize, backlog: usize) -> Result<usize, SystemError> {
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let mut socket = unsafe { socket.inner_no_preempt() };
|
|
|
- socket.listen(backlog)?;
|
|
|
- return Ok(0);
|
|
|
+ let inode = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
+ inode.listen(backlog).map(|_| 0)
|
|
|
}
|
|
|
|
|
|
/// @brief sys_shutdown系统调用的实际执行函数
|
|
|
@@ -344,12 +355,8 @@ impl Syscall {
|
|
|
///
|
|
|
/// @return 成功返回0,失败返回错误码
|
|
|
pub fn shutdown(fd: usize, how: usize) -> Result<usize, SystemError> {
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let mut socket = unsafe { socket.inner_no_preempt() };
|
|
|
- socket.shutdown(ShutdownType::from_bits_truncate((how + 1) as u8))?;
|
|
|
- return Ok(0);
|
|
|
+ let inode = ProcessManager::current_pcb().get_socket(fd as i32)?;
|
|
|
+ inode.shutdown(ShutdownBit::try_from(how)?).map(|()| 0)
|
|
|
}
|
|
|
|
|
|
/// @brief sys_accept系统调用的实际执行函数
|
|
|
@@ -404,18 +411,14 @@ impl Syscall {
|
|
|
addrlen: *mut u32,
|
|
|
flags: u32,
|
|
|
) -> Result<usize, SystemError> {
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- // debug!("accept: socket={:?}", socket);
|
|
|
- let mut socket = unsafe { socket.inner_no_preempt() };
|
|
|
- // 从socket中接收连接
|
|
|
- let (new_socket, remote_endpoint) = socket.accept()?;
|
|
|
- drop(socket);
|
|
|
+ let (new_socket, remote_endpoint) = {
|
|
|
+ ProcessManager::current_pcb()
|
|
|
+ .get_socket(fd as i32)?
|
|
|
+ .accept()?
|
|
|
+ };
|
|
|
|
|
|
// debug!("accept: new_socket={:?}", new_socket);
|
|
|
// Insert the new socket into the file descriptor vector
|
|
|
- let new_socket: Arc<SocketInode> = SocketInode::new(new_socket);
|
|
|
|
|
|
let mut file_mode = FileMode::O_RDWR;
|
|
|
if flags & SOCK_NONBLOCK.bits() != 0 {
|
|
|
@@ -431,12 +434,8 @@ impl Syscall {
|
|
|
.alloc_fd(File::new(new_socket, file_mode)?, None)?;
|
|
|
// debug!("accept: new_fd={}", new_fd);
|
|
|
if !addr.is_null() {
|
|
|
- // debug!("accept: write remote_endpoint to user");
|
|
|
// 将对端地址写入用户空间
|
|
|
- let sockaddr_in = SockAddr::from(remote_endpoint);
|
|
|
- unsafe {
|
|
|
- sockaddr_in.write_to_user(addr, addrlen)?;
|
|
|
- }
|
|
|
+ remote_endpoint.write_to_user(addr, addrlen)?;
|
|
|
}
|
|
|
return Ok(new_fd as usize);
|
|
|
}
|
|
|
@@ -459,17 +458,10 @@ impl Syscall {
|
|
|
if addr.is_null() {
|
|
|
return Err(SystemError::EINVAL);
|
|
|
}
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let socket = socket.inner();
|
|
|
- let endpoint: Endpoint = socket.endpoint().ok_or(SystemError::EINVAL)?;
|
|
|
- drop(socket);
|
|
|
-
|
|
|
- let sockaddr_in = SockAddr::from(endpoint);
|
|
|
- unsafe {
|
|
|
- sockaddr_in.write_to_user(addr, addrlen)?;
|
|
|
- }
|
|
|
+ ProcessManager::current_pcb()
|
|
|
+ .get_socket(fd as i32)?
|
|
|
+ .local_endpoint()?
|
|
|
+ .write_to_user(addr, addrlen)?;
|
|
|
return Ok(0);
|
|
|
}
|
|
|
|
|
|
@@ -489,555 +481,11 @@ impl Syscall {
|
|
|
return Err(SystemError::EINVAL);
|
|
|
}
|
|
|
|
|
|
- let socket: Arc<SocketInode> = ProcessManager::current_pcb()
|
|
|
- .get_socket(fd as i32)
|
|
|
- .ok_or(SystemError::EBADF)?;
|
|
|
- let socket = socket.inner();
|
|
|
- let endpoint: Endpoint = socket.peer_endpoint().ok_or(SystemError::EINVAL)?;
|
|
|
- drop(socket);
|
|
|
+ ProcessManager::current_pcb()
|
|
|
+ .get_socket(fd as i32)?
|
|
|
+ .remote_endpoint()?
|
|
|
+ .write_to_user(addr, addrlen)?;
|
|
|
|
|
|
- let sockaddr_in = SockAddr::from(endpoint);
|
|
|
- unsafe {
|
|
|
- sockaddr_in.write_to_user(addr, addrlen)?;
|
|
|
- }
|
|
|
return Ok(0);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-// 参考资料: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html#tag_13_32
|
|
|
-#[repr(C)]
|
|
|
-#[derive(Debug, Clone, Copy)]
|
|
|
-pub struct SockAddrIn {
|
|
|
- pub sin_family: u16,
|
|
|
- pub sin_port: u16,
|
|
|
- pub sin_addr: u32,
|
|
|
- pub sin_zero: [u8; 8],
|
|
|
-}
|
|
|
-
|
|
|
-#[repr(C)]
|
|
|
-#[derive(Debug, Clone, Copy)]
|
|
|
-pub struct SockAddrUn {
|
|
|
- pub sun_family: u16,
|
|
|
- pub sun_path: [u8; 108],
|
|
|
-}
|
|
|
-
|
|
|
-#[repr(C)]
|
|
|
-#[derive(Debug, Clone, Copy)]
|
|
|
-pub struct SockAddrLl {
|
|
|
- pub sll_family: u16,
|
|
|
- pub sll_protocol: u16,
|
|
|
- pub sll_ifindex: u32,
|
|
|
- pub sll_hatype: u16,
|
|
|
- pub sll_pkttype: u8,
|
|
|
- pub sll_halen: u8,
|
|
|
- pub sll_addr: [u8; 8],
|
|
|
-}
|
|
|
-
|
|
|
-#[repr(C)]
|
|
|
-#[derive(Debug, Clone, Copy)]
|
|
|
-pub struct SockAddrNl {
|
|
|
- nl_family: u16,
|
|
|
- nl_pad: u16,
|
|
|
- nl_pid: u32,
|
|
|
- nl_groups: u32,
|
|
|
-}
|
|
|
-
|
|
|
-#[repr(C)]
|
|
|
-#[derive(Debug, Clone, Copy)]
|
|
|
-pub struct SockAddrPlaceholder {
|
|
|
- pub family: u16,
|
|
|
- pub data: [u8; 14],
|
|
|
-}
|
|
|
-
|
|
|
-#[repr(C)]
|
|
|
-#[derive(Clone, Copy)]
|
|
|
-pub union SockAddr {
|
|
|
- pub family: u16,
|
|
|
- pub addr_in: SockAddrIn,
|
|
|
- pub addr_un: SockAddrUn,
|
|
|
- pub addr_ll: SockAddrLl,
|
|
|
- pub addr_nl: SockAddrNl,
|
|
|
- pub addr_ph: SockAddrPlaceholder,
|
|
|
-}
|
|
|
-
|
|
|
-impl SockAddr {
|
|
|
- /// @brief 把用户传入的SockAddr转换为Endpoint结构体
|
|
|
- pub fn to_endpoint(addr: *const SockAddr, len: usize) -> Result<Endpoint, SystemError> {
|
|
|
- verify_area(
|
|
|
- VirtAddr::new(addr as usize),
|
|
|
- core::mem::size_of::<SockAddr>(),
|
|
|
- )
|
|
|
- .map_err(|_| SystemError::EFAULT)?;
|
|
|
-
|
|
|
- let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?;
|
|
|
- unsafe {
|
|
|
- match AddressFamily::try_from(addr.family)? {
|
|
|
- AddressFamily::INet => {
|
|
|
- if len < addr.len()? {
|
|
|
- return Err(SystemError::EINVAL);
|
|
|
- }
|
|
|
-
|
|
|
- let addr_in: SockAddrIn = addr.addr_in;
|
|
|
-
|
|
|
- let ip: wire::IpAddress = wire::IpAddress::from(wire::Ipv4Address::from_bytes(
|
|
|
- &u32::from_be(addr_in.sin_addr).to_be_bytes()[..],
|
|
|
- ));
|
|
|
- let port = u16::from_be(addr_in.sin_port);
|
|
|
-
|
|
|
- return Ok(Endpoint::Ip(Some(wire::IpEndpoint::new(ip, port))));
|
|
|
- }
|
|
|
- AddressFamily::Unix => {
|
|
|
- let addr_un: SockAddrUn = addr.addr_un;
|
|
|
-
|
|
|
- let path = CStr::from_bytes_until_nul(&addr_un.sun_path)
|
|
|
- .map_err(|_| SystemError::EINVAL)?
|
|
|
- .to_str()
|
|
|
- .map_err(|_| SystemError::EINVAL)?;
|
|
|
-
|
|
|
- let fd = do_sys_open(
|
|
|
- AtFlags::AT_FDCWD.bits(),
|
|
|
- path,
|
|
|
- FileMode::O_RDWR,
|
|
|
- ModeType::S_IWUGO | ModeType::S_IRUGO,
|
|
|
- true,
|
|
|
- )?;
|
|
|
-
|
|
|
- let binding = ProcessManager::current_pcb().fd_table();
|
|
|
- let fd_table_guard = binding.read();
|
|
|
-
|
|
|
- let file = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
|
|
|
- if file.file_type() != FileType::Socket {
|
|
|
- return Err(SystemError::ENOTSOCK);
|
|
|
- }
|
|
|
- let inode = file.inode();
|
|
|
- let socketinode = inode.as_any_ref().downcast_ref::<Arc<SocketInode>>();
|
|
|
-
|
|
|
- return Ok(Endpoint::Inode(socketinode.cloned()));
|
|
|
- }
|
|
|
- AddressFamily::Packet => {
|
|
|
- // TODO: support packet socket
|
|
|
- return Err(SystemError::EINVAL);
|
|
|
- }
|
|
|
- AddressFamily::Netlink => {
|
|
|
- // TODO: support netlink socket
|
|
|
- return Err(SystemError::EINVAL);
|
|
|
- }
|
|
|
- _ => {
|
|
|
- return Err(SystemError::EINVAL);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// @brief 获取地址长度
|
|
|
- pub fn len(&self) -> Result<usize, SystemError> {
|
|
|
- let ret = match AddressFamily::try_from(unsafe { self.family })? {
|
|
|
- AddressFamily::INet => Ok(core::mem::size_of::<SockAddrIn>()),
|
|
|
- AddressFamily::Packet => Ok(core::mem::size_of::<SockAddrLl>()),
|
|
|
- AddressFamily::Netlink => Ok(core::mem::size_of::<SockAddrNl>()),
|
|
|
- AddressFamily::Unix => Err(SystemError::EINVAL),
|
|
|
- _ => Err(SystemError::EINVAL),
|
|
|
- };
|
|
|
-
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- /// @brief 把SockAddr的数据写入用户空间
|
|
|
- ///
|
|
|
- /// @param addr 用户空间的SockAddr的地址
|
|
|
- /// @param len 要写入的长度
|
|
|
- ///
|
|
|
- /// @return 成功返回写入的长度,失败返回错误码
|
|
|
- pub unsafe fn write_to_user(
|
|
|
- &self,
|
|
|
- addr: *mut SockAddr,
|
|
|
- addr_len: *mut u32,
|
|
|
- ) -> Result<usize, SystemError> {
|
|
|
- // 当用户传入的地址或者长度为空时,直接返回0
|
|
|
- if addr.is_null() || addr_len.is_null() {
|
|
|
- return Ok(0);
|
|
|
- }
|
|
|
-
|
|
|
- // 检查用户传入的地址是否合法
|
|
|
- verify_area(
|
|
|
- VirtAddr::new(addr as usize),
|
|
|
- core::mem::size_of::<SockAddr>(),
|
|
|
- )
|
|
|
- .map_err(|_| SystemError::EFAULT)?;
|
|
|
-
|
|
|
- verify_area(
|
|
|
- VirtAddr::new(addr_len as usize),
|
|
|
- core::mem::size_of::<u32>(),
|
|
|
- )
|
|
|
- .map_err(|_| SystemError::EFAULT)?;
|
|
|
-
|
|
|
- let to_write = min(self.len()?, *addr_len as usize);
|
|
|
- if to_write > 0 {
|
|
|
- let buf = core::slice::from_raw_parts_mut(addr as *mut u8, to_write);
|
|
|
- buf.copy_from_slice(core::slice::from_raw_parts(
|
|
|
- self as *const SockAddr as *const u8,
|
|
|
- to_write,
|
|
|
- ));
|
|
|
- }
|
|
|
- *addr_len = self.len()? as u32;
|
|
|
- return Ok(to_write);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl From<Endpoint> for SockAddr {
|
|
|
- fn from(value: Endpoint) -> Self {
|
|
|
- match value {
|
|
|
- Endpoint::Ip(ip_endpoint) => {
|
|
|
- // 未指定地址
|
|
|
- if ip_endpoint.is_none() {
|
|
|
- return SockAddr {
|
|
|
- addr_ph: SockAddrPlaceholder {
|
|
|
- family: AddressFamily::Unspecified as u16,
|
|
|
- data: [0; 14],
|
|
|
- },
|
|
|
- };
|
|
|
- }
|
|
|
- // 指定了地址
|
|
|
- let ip_endpoint = ip_endpoint.unwrap();
|
|
|
- match ip_endpoint.addr {
|
|
|
- wire::IpAddress::Ipv4(ipv4_addr) => {
|
|
|
- let addr_in = SockAddrIn {
|
|
|
- sin_family: AddressFamily::INet as u16,
|
|
|
- sin_port: ip_endpoint.port.to_be(),
|
|
|
- sin_addr: u32::from_be_bytes(ipv4_addr.0).to_be(),
|
|
|
- sin_zero: [0; 8],
|
|
|
- };
|
|
|
-
|
|
|
- return SockAddr { addr_in };
|
|
|
- }
|
|
|
- _ => {
|
|
|
- unimplemented!("not support ipv6");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Endpoint::LinkLayer(link_endpoint) => {
|
|
|
- let addr_ll = SockAddrLl {
|
|
|
- sll_family: AddressFamily::Packet as u16,
|
|
|
- sll_protocol: 0,
|
|
|
- sll_ifindex: link_endpoint.interface as u32,
|
|
|
- sll_hatype: 0,
|
|
|
- sll_pkttype: 0,
|
|
|
- sll_halen: 0,
|
|
|
- sll_addr: [0; 8],
|
|
|
- };
|
|
|
-
|
|
|
- return SockAddr { addr_ll };
|
|
|
- }
|
|
|
-
|
|
|
- _ => {
|
|
|
- // todo: support other endpoint, like Netlink...
|
|
|
- unimplemented!("not support {value:?}");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#[repr(C)]
|
|
|
-#[derive(Debug, Clone, Copy)]
|
|
|
-pub struct MsgHdr {
|
|
|
- /// 指向一个SockAddr结构体的指针
|
|
|
- pub msg_name: *mut SockAddr,
|
|
|
- /// SockAddr结构体的大小
|
|
|
- pub msg_namelen: u32,
|
|
|
- /// scatter/gather array
|
|
|
- pub msg_iov: *mut IoVec,
|
|
|
- /// elements in msg_iov
|
|
|
- pub msg_iovlen: usize,
|
|
|
- /// 辅助数据
|
|
|
- pub msg_control: *mut u8,
|
|
|
- /// 辅助数据长度
|
|
|
- pub msg_controllen: usize,
|
|
|
- /// 接收到的消息的标志
|
|
|
- pub msg_flags: u32,
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
|
|
-pub enum PosixIpProtocol {
|
|
|
- /// Dummy protocol for TCP.
|
|
|
- IP = 0,
|
|
|
- /// Internet Control Message Protocol.
|
|
|
- ICMP = 1,
|
|
|
- /// Internet Group Management Protocol.
|
|
|
- IGMP = 2,
|
|
|
- /// IPIP tunnels (older KA9Q tunnels use 94).
|
|
|
- IPIP = 4,
|
|
|
- /// Transmission Control Protocol.
|
|
|
- TCP = 6,
|
|
|
- /// Exterior Gateway Protocol.
|
|
|
- EGP = 8,
|
|
|
- /// PUP protocol.
|
|
|
- PUP = 12,
|
|
|
- /// User Datagram Protocol.
|
|
|
- UDP = 17,
|
|
|
- /// XNS IDP protocol.
|
|
|
- IDP = 22,
|
|
|
- /// SO Transport Protocol Class 4.
|
|
|
- TP = 29,
|
|
|
- /// Datagram Congestion Control Protocol.
|
|
|
- DCCP = 33,
|
|
|
- /// IPv6-in-IPv4 tunnelling.
|
|
|
- IPv6 = 41,
|
|
|
- /// RSVP Protocol.
|
|
|
- RSVP = 46,
|
|
|
- /// Generic Routing Encapsulation. (Cisco GRE) (rfc 1701, 1702)
|
|
|
- GRE = 47,
|
|
|
- /// Encapsulation Security Payload protocol
|
|
|
- ESP = 50,
|
|
|
- /// Authentication Header protocol
|
|
|
- AH = 51,
|
|
|
- /// Multicast Transport Protocol.
|
|
|
- MTP = 92,
|
|
|
- /// IP option pseudo header for BEET
|
|
|
- BEETPH = 94,
|
|
|
- /// Encapsulation Header.
|
|
|
- ENCAP = 98,
|
|
|
- /// Protocol Independent Multicast.
|
|
|
- PIM = 103,
|
|
|
- /// Compression Header Protocol.
|
|
|
- COMP = 108,
|
|
|
- /// Stream Control Transport Protocol
|
|
|
- SCTP = 132,
|
|
|
- /// UDP-Lite protocol (RFC 3828)
|
|
|
- UDPLITE = 136,
|
|
|
- /// MPLS in IP (RFC 4023)
|
|
|
- MPLSINIP = 137,
|
|
|
- /// Ethernet-within-IPv6 Encapsulation
|
|
|
- ETHERNET = 143,
|
|
|
- /// Raw IP packets
|
|
|
- RAW = 255,
|
|
|
- /// Multipath TCP connection
|
|
|
- MPTCP = 262,
|
|
|
-}
|
|
|
-
|
|
|
-impl TryFrom<u16> for PosixIpProtocol {
|
|
|
- type Error = SystemError;
|
|
|
-
|
|
|
- fn try_from(value: u16) -> Result<Self, Self::Error> {
|
|
|
- match <Self as FromPrimitive>::from_u16(value) {
|
|
|
- Some(p) => Ok(p),
|
|
|
- None => Err(SystemError::EPROTONOSUPPORT),
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl From<PosixIpProtocol> for u16 {
|
|
|
- fn from(value: PosixIpProtocol) -> Self {
|
|
|
- <PosixIpProtocol as ToPrimitive>::to_u16(&value).unwrap()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#[allow(non_camel_case_types)]
|
|
|
-#[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
|
|
-pub enum PosixSocketOption {
|
|
|
- SO_DEBUG = 1,
|
|
|
- SO_REUSEADDR = 2,
|
|
|
- SO_TYPE = 3,
|
|
|
- SO_ERROR = 4,
|
|
|
- SO_DONTROUTE = 5,
|
|
|
- SO_BROADCAST = 6,
|
|
|
- SO_SNDBUF = 7,
|
|
|
- SO_RCVBUF = 8,
|
|
|
- SO_SNDBUFFORCE = 32,
|
|
|
- SO_RCVBUFFORCE = 33,
|
|
|
- SO_KEEPALIVE = 9,
|
|
|
- SO_OOBINLINE = 10,
|
|
|
- SO_NO_CHECK = 11,
|
|
|
- SO_PRIORITY = 12,
|
|
|
- SO_LINGER = 13,
|
|
|
- SO_BSDCOMPAT = 14,
|
|
|
- SO_REUSEPORT = 15,
|
|
|
- SO_PASSCRED = 16,
|
|
|
- SO_PEERCRED = 17,
|
|
|
- SO_RCVLOWAT = 18,
|
|
|
- SO_SNDLOWAT = 19,
|
|
|
- SO_RCVTIMEO_OLD = 20,
|
|
|
- SO_SNDTIMEO_OLD = 21,
|
|
|
-
|
|
|
- SO_SECURITY_AUTHENTICATION = 22,
|
|
|
- SO_SECURITY_ENCRYPTION_TRANSPORT = 23,
|
|
|
- SO_SECURITY_ENCRYPTION_NETWORK = 24,
|
|
|
-
|
|
|
- SO_BINDTODEVICE = 25,
|
|
|
-
|
|
|
- /// 与SO_GET_FILTER相同
|
|
|
- SO_ATTACH_FILTER = 26,
|
|
|
- SO_DETACH_FILTER = 27,
|
|
|
-
|
|
|
- SO_PEERNAME = 28,
|
|
|
-
|
|
|
- SO_ACCEPTCONN = 30,
|
|
|
-
|
|
|
- SO_PEERSEC = 31,
|
|
|
- SO_PASSSEC = 34,
|
|
|
-
|
|
|
- SO_MARK = 36,
|
|
|
-
|
|
|
- SO_PROTOCOL = 38,
|
|
|
- SO_DOMAIN = 39,
|
|
|
-
|
|
|
- SO_RXQ_OVFL = 40,
|
|
|
-
|
|
|
- /// 与SCM_WIFI_STATUS相同
|
|
|
- SO_WIFI_STATUS = 41,
|
|
|
- SO_PEEK_OFF = 42,
|
|
|
-
|
|
|
- /* Instruct lower device to use last 4-bytes of skb data as FCS */
|
|
|
- SO_NOFCS = 43,
|
|
|
-
|
|
|
- SO_LOCK_FILTER = 44,
|
|
|
- SO_SELECT_ERR_QUEUE = 45,
|
|
|
- SO_BUSY_POLL = 46,
|
|
|
- SO_MAX_PACING_RATE = 47,
|
|
|
- SO_BPF_EXTENSIONS = 48,
|
|
|
- SO_INCOMING_CPU = 49,
|
|
|
- SO_ATTACH_BPF = 50,
|
|
|
- // SO_DETACH_BPF = SO_DETACH_FILTER,
|
|
|
- SO_ATTACH_REUSEPORT_CBPF = 51,
|
|
|
- SO_ATTACH_REUSEPORT_EBPF = 52,
|
|
|
-
|
|
|
- SO_CNX_ADVICE = 53,
|
|
|
- SCM_TIMESTAMPING_OPT_STATS = 54,
|
|
|
- SO_MEMINFO = 55,
|
|
|
- SO_INCOMING_NAPI_ID = 56,
|
|
|
- SO_COOKIE = 57,
|
|
|
- SCM_TIMESTAMPING_PKTINFO = 58,
|
|
|
- SO_PEERGROUPS = 59,
|
|
|
- SO_ZEROCOPY = 60,
|
|
|
- /// 与SCM_TXTIME相同
|
|
|
- SO_TXTIME = 61,
|
|
|
-
|
|
|
- SO_BINDTOIFINDEX = 62,
|
|
|
-
|
|
|
- SO_TIMESTAMP_OLD = 29,
|
|
|
- SO_TIMESTAMPNS_OLD = 35,
|
|
|
- SO_TIMESTAMPING_OLD = 37,
|
|
|
- SO_TIMESTAMP_NEW = 63,
|
|
|
- SO_TIMESTAMPNS_NEW = 64,
|
|
|
- SO_TIMESTAMPING_NEW = 65,
|
|
|
-
|
|
|
- SO_RCVTIMEO_NEW = 66,
|
|
|
- SO_SNDTIMEO_NEW = 67,
|
|
|
-
|
|
|
- SO_DETACH_REUSEPORT_BPF = 68,
|
|
|
-
|
|
|
- SO_PREFER_BUSY_POLL = 69,
|
|
|
- SO_BUSY_POLL_BUDGET = 70,
|
|
|
-
|
|
|
- SO_NETNS_COOKIE = 71,
|
|
|
- SO_BUF_LOCK = 72,
|
|
|
- SO_RESERVE_MEM = 73,
|
|
|
- SO_TXREHASH = 74,
|
|
|
- SO_RCVMARK = 75,
|
|
|
-}
|
|
|
-
|
|
|
-impl TryFrom<i32> for PosixSocketOption {
|
|
|
- type Error = SystemError;
|
|
|
-
|
|
|
- fn try_from(value: i32) -> Result<Self, Self::Error> {
|
|
|
- match <Self as FromPrimitive>::from_i32(value) {
|
|
|
- Some(p) => Ok(p),
|
|
|
- None => Err(SystemError::EINVAL),
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl From<PosixSocketOption> for i32 {
|
|
|
- fn from(value: PosixSocketOption) -> Self {
|
|
|
- <PosixSocketOption as ToPrimitive>::to_i32(&value).unwrap()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
|
|
-pub enum PosixTcpSocketOptions {
|
|
|
- /// Turn off Nagle's algorithm.
|
|
|
- NoDelay = 1,
|
|
|
- /// Limit MSS.
|
|
|
- MaxSegment = 2,
|
|
|
- /// Never send partially complete segments.
|
|
|
- Cork = 3,
|
|
|
- /// Start keeplives after this period.
|
|
|
- KeepIdle = 4,
|
|
|
- /// Interval between keepalives.
|
|
|
- KeepIntvl = 5,
|
|
|
- /// Number of keepalives before death.
|
|
|
- KeepCnt = 6,
|
|
|
- /// Number of SYN retransmits.
|
|
|
- Syncnt = 7,
|
|
|
- /// Lifetime for orphaned FIN-WAIT-2 state.
|
|
|
- Linger2 = 8,
|
|
|
- /// Wake up listener only when data arrive.
|
|
|
- DeferAccept = 9,
|
|
|
- /// Bound advertised window
|
|
|
- WindowClamp = 10,
|
|
|
- /// Information about this connection.
|
|
|
- Info = 11,
|
|
|
- /// Block/reenable quick acks.
|
|
|
- QuickAck = 12,
|
|
|
- /// Congestion control algorithm.
|
|
|
- Congestion = 13,
|
|
|
- /// TCP MD5 Signature (RFC2385).
|
|
|
- Md5Sig = 14,
|
|
|
- /// Use linear timeouts for thin streams
|
|
|
- ThinLinearTimeouts = 16,
|
|
|
- /// Fast retrans. after 1 dupack.
|
|
|
- ThinDupack = 17,
|
|
|
- /// How long for loss retry before timeout.
|
|
|
- UserTimeout = 18,
|
|
|
- /// TCP sock is under repair right now.
|
|
|
- Repair = 19,
|
|
|
- RepairQueue = 20,
|
|
|
- QueueSeq = 21,
|
|
|
- RepairOptions = 22,
|
|
|
- /// Enable FastOpen on listeners
|
|
|
- FastOpen = 23,
|
|
|
- Timestamp = 24,
|
|
|
- /// Limit number of unsent bytes in write queue.
|
|
|
- NotSentLowat = 25,
|
|
|
- /// Get Congestion Control (optional) info.
|
|
|
- CCInfo = 26,
|
|
|
- /// Record SYN headers for new connections.
|
|
|
- SaveSyn = 27,
|
|
|
- /// Get SYN headers recorded for connection.
|
|
|
- SavedSyn = 28,
|
|
|
- /// Get/set window parameters.
|
|
|
- RepairWindow = 29,
|
|
|
- /// Attempt FastOpen with connect.
|
|
|
- FastOpenConnect = 30,
|
|
|
- /// Attach a ULP to a TCP connection.
|
|
|
- ULP = 31,
|
|
|
- /// TCP MD5 Signature with extensions.
|
|
|
- Md5SigExt = 32,
|
|
|
- /// Set the key for Fast Open(cookie).
|
|
|
- FastOpenKey = 33,
|
|
|
- /// Enable TFO without a TFO cookie.
|
|
|
- FastOpenNoCookie = 34,
|
|
|
- ZeroCopyReceive = 35,
|
|
|
- /// Notify bytes available to read as a cmsg on read.
|
|
|
- /// 与TCP_CM_INQ相同
|
|
|
- INQ = 36,
|
|
|
- /// delay outgoing packets by XX usec
|
|
|
- TxDelay = 37,
|
|
|
-}
|
|
|
-
|
|
|
-impl TryFrom<i32> for PosixTcpSocketOptions {
|
|
|
- type Error = SystemError;
|
|
|
-
|
|
|
- fn try_from(value: i32) -> Result<Self, Self::Error> {
|
|
|
- match <Self as FromPrimitive>::from_i32(value) {
|
|
|
- Some(p) => Ok(p),
|
|
|
- None => Err(SystemError::EINVAL),
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl From<PosixTcpSocketOptions> for i32 {
|
|
|
- fn from(val: PosixTcpSocketOptions) -> Self {
|
|
|
- <PosixTcpSocketOptions as ToPrimitive>::to_i32(&val).unwrap()
|
|
|
- }
|
|
|
-}
|