|
@@ -1,311 +1,26 @@
|
|
|
-#![allow(dead_code)]
|
|
|
-use alloc::{
|
|
|
- boxed::Box,
|
|
|
- collections::LinkedList,
|
|
|
- sync::{Arc, Weak},
|
|
|
- vec::Vec,
|
|
|
-};
|
|
|
-use hashbrown::HashMap;
|
|
|
+use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
|
|
use smoltcp::{
|
|
|
- iface::{SocketHandle, SocketSet},
|
|
|
- socket::{
|
|
|
- self, raw,
|
|
|
- tcp::{self, State},
|
|
|
- udp,
|
|
|
- },
|
|
|
+ iface::SocketHandle,
|
|
|
+ socket::{raw, tcp, udp},
|
|
|
wire,
|
|
|
};
|
|
|
use system_error::SystemError;
|
|
|
|
|
|
use crate::{
|
|
|
- arch::{rand::rand, sched::sched},
|
|
|
driver::net::NetDriver,
|
|
|
- filesystem::vfs::{syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata},
|
|
|
kerror, kwarn,
|
|
|
- libs::{
|
|
|
- rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
|
|
|
- spinlock::{SpinLock, SpinLockGuard},
|
|
|
- wait_queue::EventWaitQueue,
|
|
|
+ libs::{rwlock::RwLock, spinlock::SpinLock},
|
|
|
+ net::{
|
|
|
+ event_poll::EPollEventType, net_core::poll_ifaces, Endpoint, Protocol, ShutdownType,
|
|
|
+ NET_DRIVERS,
|
|
|
},
|
|
|
};
|
|
|
|
|
|
use super::{
|
|
|
- event_poll::{EPollEventType, EPollItem, EventPoll},
|
|
|
- net_core::poll_ifaces,
|
|
|
- Endpoint, Protocol, ShutdownType, Socket, NET_DRIVERS,
|
|
|
+ GlobalSocketHandle, Socket, SocketHandleItem, SocketMetadata, SocketOptions, SocketPollMethod,
|
|
|
+ SocketType, SocketpairOps, HANDLE_MAP, PORT_MANAGER, SOCKET_SET,
|
|
|
};
|
|
|
|
|
|
-lazy_static! {
|
|
|
- /// 所有socket的集合
|
|
|
- /// TODO: 优化这里,自己实现SocketSet!!!现在这样的话,不管全局有多少个网卡,每个时间点都只会有1个进程能够访问socket
|
|
|
- pub static ref SOCKET_SET: SpinLock<SocketSet<'static >> = SpinLock::new(SocketSet::new(vec![]));
|
|
|
- /// SocketHandle表,每个SocketHandle对应一个SocketHandleItem,
|
|
|
- /// 注意!:在网卡中断中需要拿到这张表的🔓,在获取读锁时应该确保关中断避免死锁
|
|
|
- pub static ref HANDLE_MAP: RwLock<HashMap<SocketHandle,SocketHandleItem>> = RwLock::new(HashMap::new());
|
|
|
- /// 端口管理器
|
|
|
- pub static ref PORT_MANAGER: PortManager = PortManager::new();
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(Debug)]
|
|
|
-pub struct SocketHandleItem {
|
|
|
- /// socket元数据
|
|
|
- metadata: SocketMetadata,
|
|
|
- /// shutdown状态
|
|
|
- pub shutdown_type: RwLock<ShutdownType>,
|
|
|
- /// socket的waitqueue
|
|
|
- pub wait_queue: EventWaitQueue,
|
|
|
- /// epitems,考虑写在这是否是最优解?
|
|
|
- pub epitems: SpinLock<LinkedList<Arc<EPollItem>>>,
|
|
|
-}
|
|
|
-
|
|
|
-impl SocketHandleItem {
|
|
|
- pub fn new(socket: &Box<dyn Socket>) -> Self {
|
|
|
- Self {
|
|
|
- metadata: socket.metadata().unwrap(),
|
|
|
- shutdown_type: RwLock::new(ShutdownType::empty()),
|
|
|
- wait_queue: EventWaitQueue::new(),
|
|
|
- epitems: SpinLock::new(LinkedList::new()),
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pub fn from_socket<A: Socket>(socket: &Box<A>) -> Self {
|
|
|
- Self {
|
|
|
- metadata: socket.metadata().unwrap(),
|
|
|
- shutdown_type: RwLock::new(ShutdownType::empty()),
|
|
|
- wait_queue: EventWaitQueue::new(),
|
|
|
- epitems: SpinLock::new(LinkedList::new()),
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// ### 在socket的等待队列上睡眠
|
|
|
- pub fn sleep(
|
|
|
- socket_handle: SocketHandle,
|
|
|
- events: u64,
|
|
|
- handle_map_guard: RwLockReadGuard<'_, HashMap<SocketHandle, SocketHandleItem>>,
|
|
|
- ) {
|
|
|
- unsafe {
|
|
|
- handle_map_guard
|
|
|
- .get(&socket_handle)
|
|
|
- .unwrap()
|
|
|
- .wait_queue
|
|
|
- .sleep_without_schedule(events)
|
|
|
- };
|
|
|
- drop(handle_map_guard);
|
|
|
- sched();
|
|
|
- }
|
|
|
-
|
|
|
- pub fn shutdown_type(&self) -> ShutdownType {
|
|
|
- self.shutdown_type.read().clone()
|
|
|
- }
|
|
|
-
|
|
|
- pub fn shutdown_type_writer(&mut self) -> RwLockWriteGuard<ShutdownType> {
|
|
|
- self.shutdown_type.write_irqsave()
|
|
|
- }
|
|
|
-
|
|
|
- pub fn add_epoll(&mut self, epitem: Arc<EPollItem>) {
|
|
|
- self.epitems.lock_irqsave().push_back(epitem)
|
|
|
- }
|
|
|
-
|
|
|
- pub fn remove_epoll(&mut self, epoll: &Weak<SpinLock<EventPoll>>) -> Result<(), SystemError> {
|
|
|
- let is_remove = !self
|
|
|
- .epitems
|
|
|
- .lock_irqsave()
|
|
|
- .extract_if(|x| x.epoll().ptr_eq(epoll))
|
|
|
- .collect::<Vec<_>>()
|
|
|
- .is_empty();
|
|
|
-
|
|
|
- if is_remove {
|
|
|
- return Ok(());
|
|
|
- }
|
|
|
-
|
|
|
- Err(SystemError::ENOENT)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/// @brief TCP 和 UDP 的端口管理器。
|
|
|
-/// 如果 TCP/UDP 的 socket 绑定了某个端口,它会在对应的表中记录,以检测端口冲突。
|
|
|
-pub struct PortManager {
|
|
|
- // TCP 端口记录表
|
|
|
- tcp_port_table: SpinLock<HashMap<u16, Arc<GlobalSocketHandle>>>,
|
|
|
- // UDP 端口记录表
|
|
|
- udp_port_table: SpinLock<HashMap<u16, Arc<GlobalSocketHandle>>>,
|
|
|
-}
|
|
|
-
|
|
|
-impl PortManager {
|
|
|
- pub fn new() -> Self {
|
|
|
- return Self {
|
|
|
- tcp_port_table: SpinLock::new(HashMap::new()),
|
|
|
- udp_port_table: SpinLock::new(HashMap::new()),
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- /// @brief 自动分配一个相对应协议中未被使用的PORT,如果动态端口均已被占用,返回错误码 EADDRINUSE
|
|
|
- pub fn get_ephemeral_port(&self, socket_type: SocketType) -> Result<u16, SystemError> {
|
|
|
- // TODO: selects non-conflict high port
|
|
|
-
|
|
|
- static mut EPHEMERAL_PORT: u16 = 0;
|
|
|
- unsafe {
|
|
|
- if EPHEMERAL_PORT == 0 {
|
|
|
- EPHEMERAL_PORT = (49152 + rand() % (65536 - 49152)) as u16;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- let mut remaining = 65536 - 49152; // 剩余尝试分配端口次数
|
|
|
- let mut port: u16;
|
|
|
- while remaining > 0 {
|
|
|
- unsafe {
|
|
|
- if EPHEMERAL_PORT == 65535 {
|
|
|
- EPHEMERAL_PORT = 49152;
|
|
|
- } else {
|
|
|
- EPHEMERAL_PORT = EPHEMERAL_PORT + 1;
|
|
|
- }
|
|
|
- port = EPHEMERAL_PORT;
|
|
|
- }
|
|
|
-
|
|
|
- // 使用 ListenTable 检查端口是否被占用
|
|
|
- let listen_table_guard = match socket_type {
|
|
|
- SocketType::UdpSocket => self.udp_port_table.lock(),
|
|
|
- SocketType::TcpSocket => self.tcp_port_table.lock(),
|
|
|
- SocketType::RawSocket => panic!("RawSocket cann't get a port"),
|
|
|
- };
|
|
|
- if let None = listen_table_guard.get(&port) {
|
|
|
- drop(listen_table_guard);
|
|
|
- return Ok(port);
|
|
|
- }
|
|
|
- remaining -= 1;
|
|
|
- }
|
|
|
- return Err(SystemError::EADDRINUSE);
|
|
|
- }
|
|
|
-
|
|
|
- /// @brief 检测给定端口是否已被占用,如果未被占用则在 TCP/UDP 对应的表中记录
|
|
|
- ///
|
|
|
- /// TODO: 增加支持端口复用的逻辑
|
|
|
- pub fn bind_port(
|
|
|
- &self,
|
|
|
- socket_type: SocketType,
|
|
|
- port: u16,
|
|
|
- handle: Arc<GlobalSocketHandle>,
|
|
|
- ) -> Result<(), SystemError> {
|
|
|
- if port > 0 {
|
|
|
- let mut listen_table_guard = match socket_type {
|
|
|
- SocketType::UdpSocket => self.udp_port_table.lock(),
|
|
|
- SocketType::TcpSocket => self.tcp_port_table.lock(),
|
|
|
- SocketType::RawSocket => panic!("RawSocket cann't bind a port"),
|
|
|
- };
|
|
|
- match listen_table_guard.get(&port) {
|
|
|
- Some(_) => return Err(SystemError::EADDRINUSE),
|
|
|
- None => listen_table_guard.insert(port, handle),
|
|
|
- };
|
|
|
- drop(listen_table_guard);
|
|
|
- }
|
|
|
- return Ok(());
|
|
|
- }
|
|
|
-
|
|
|
- /// @brief 在对应的端口记录表中将端口和 socket 解绑
|
|
|
- pub fn unbind_port(&self, socket_type: SocketType, port: u16) -> Result<(), SystemError> {
|
|
|
- let mut listen_table_guard = match socket_type {
|
|
|
- SocketType::UdpSocket => self.udp_port_table.lock(),
|
|
|
- SocketType::TcpSocket => self.tcp_port_table.lock(),
|
|
|
- SocketType::RawSocket => return Ok(()),
|
|
|
- };
|
|
|
- listen_table_guard.remove(&port);
|
|
|
- drop(listen_table_guard);
|
|
|
- return Ok(());
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/* For setsockopt(2) */
|
|
|
-// See: linux-5.19.10/include/uapi/asm-generic/socket.h#9
|
|
|
-pub const SOL_SOCKET: u8 = 1;
|
|
|
-
|
|
|
-/// @brief socket的句柄管理组件。
|
|
|
-/// 它在smoltcp的SocketHandle上封装了一层,增加更多的功能。
|
|
|
-/// 比如,在socket被关闭时,自动释放socket的资源,通知系统的其他组件。
|
|
|
-#[derive(Debug)]
|
|
|
-pub struct GlobalSocketHandle(SocketHandle);
|
|
|
-
|
|
|
-impl GlobalSocketHandle {
|
|
|
- pub fn new(handle: SocketHandle) -> Arc<Self> {
|
|
|
- return Arc::new(Self(handle));
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl Clone for GlobalSocketHandle {
|
|
|
- fn clone(&self) -> Self {
|
|
|
- Self(self.0)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-impl Drop for GlobalSocketHandle {
|
|
|
- fn drop(&mut self) {
|
|
|
- let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
|
|
- socket_set_guard.remove(self.0); // 删除的时候,会发送一条FINISH的信息?
|
|
|
- drop(socket_set_guard);
|
|
|
- poll_ifaces();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/// @brief socket的类型
|
|
|
-#[derive(Debug, Clone, Copy)]
|
|
|
-pub enum SocketType {
|
|
|
- /// 原始的socket
|
|
|
- RawSocket,
|
|
|
- /// 用于Tcp通信的 Socket
|
|
|
- TcpSocket,
|
|
|
- /// 用于Udp通信的 Socket
|
|
|
- UdpSocket,
|
|
|
-}
|
|
|
-
|
|
|
-bitflags! {
|
|
|
- /// @brief socket的选项
|
|
|
- #[derive(Default)]
|
|
|
- pub struct SocketOptions: u32 {
|
|
|
- /// 是否阻塞
|
|
|
- const BLOCK = 1 << 0;
|
|
|
- /// 是否允许广播
|
|
|
- const BROADCAST = 1 << 1;
|
|
|
- /// 是否允许多播
|
|
|
- const MULTICAST = 1 << 2;
|
|
|
- /// 是否允许重用地址
|
|
|
- const REUSEADDR = 1 << 3;
|
|
|
- /// 是否允许重用端口
|
|
|
- const REUSEPORT = 1 << 4;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(Debug, Clone)]
|
|
|
-/// @brief 在trait Socket的metadata函数中返回该结构体供外部使用
|
|
|
-pub struct SocketMetadata {
|
|
|
- /// socket的类型
|
|
|
- pub socket_type: SocketType,
|
|
|
- /// 发送缓冲区的大小
|
|
|
- pub send_buf_size: usize,
|
|
|
- /// 接收缓冲区的大小
|
|
|
- pub recv_buf_size: usize,
|
|
|
- /// 元数据的缓冲区的大小
|
|
|
- pub metadata_buf_size: usize,
|
|
|
- /// socket的选项
|
|
|
- pub options: SocketOptions,
|
|
|
-}
|
|
|
-
|
|
|
-impl SocketMetadata {
|
|
|
- fn new(
|
|
|
- socket_type: SocketType,
|
|
|
- send_buf_size: usize,
|
|
|
- recv_buf_size: usize,
|
|
|
- metadata_buf_size: usize,
|
|
|
- options: SocketOptions,
|
|
|
- ) -> Self {
|
|
|
- Self {
|
|
|
- socket_type,
|
|
|
- send_buf_size,
|
|
|
- recv_buf_size,
|
|
|
- metadata_buf_size,
|
|
|
- options,
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/// @brief 表示原始的socket。原始套接字绕过传输层协议(如 TCP 或 UDP)并提供对网络层协议(如 IP)的直接访问。
|
|
|
///
|
|
|
/// ref: https://man7.org/linux/man-pages/man7/raw.7.html
|
|
@@ -323,9 +38,9 @@ pub struct RawSocket {
|
|
|
impl RawSocket {
|
|
|
/// 元数据的缓冲区的大小
|
|
|
pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024;
|
|
|
- /// 默认的发送缓冲区的大小 transmiss
|
|
|
- pub const DEFAULT_RX_BUF_SIZE: usize = 64 * 1024;
|
|
|
/// 默认的接收缓冲区的大小 receive
|
|
|
+ pub const DEFAULT_RX_BUF_SIZE: usize = 64 * 1024;
|
|
|
+ /// 默认的发送缓冲区的大小 transmiss
|
|
|
pub const DEFAULT_TX_BUF_SIZE: usize = 64 * 1024;
|
|
|
|
|
|
/// @brief 创建一个原始的socket
|
|
@@ -335,20 +50,20 @@ impl RawSocket {
|
|
|
///
|
|
|
/// @return 返回创建的原始的socket
|
|
|
pub fn new(protocol: Protocol, options: SocketOptions) -> Self {
|
|
|
- let tx_buffer = raw::PacketBuffer::new(
|
|
|
- vec![raw::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
|
|
|
- vec![0; Self::DEFAULT_TX_BUF_SIZE],
|
|
|
- );
|
|
|
let rx_buffer = raw::PacketBuffer::new(
|
|
|
vec![raw::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
|
|
|
vec![0; Self::DEFAULT_RX_BUF_SIZE],
|
|
|
);
|
|
|
+ let tx_buffer = raw::PacketBuffer::new(
|
|
|
+ vec![raw::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
|
|
|
+ vec![0; Self::DEFAULT_TX_BUF_SIZE],
|
|
|
+ );
|
|
|
let protocol: u8 = protocol.into();
|
|
|
let socket = raw::Socket::new(
|
|
|
- smoltcp::wire::IpVersion::Ipv4,
|
|
|
+ wire::IpVersion::Ipv4,
|
|
|
wire::IpProtocol::from(protocol),
|
|
|
- tx_buffer,
|
|
|
rx_buffer,
|
|
|
+ tx_buffer,
|
|
|
);
|
|
|
|
|
|
// 把socket添加到socket集合中,并得到socket的句柄
|
|
@@ -372,6 +87,14 @@ impl RawSocket {
|
|
|
}
|
|
|
|
|
|
impl Socket for RawSocket {
|
|
|
+ fn as_any_ref(&self) -> &dyn core::any::Any {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ fn as_any_mut(&mut self) -> &mut dyn core::any::Any {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
fn read(&mut self, buf: &mut [u8]) -> (Result<usize, SystemError>, Endpoint) {
|
|
|
poll_ifaces();
|
|
|
loop {
|
|
@@ -384,13 +107,13 @@ impl Socket for RawSocket {
|
|
|
let packet = wire::Ipv4Packet::new_unchecked(buf);
|
|
|
return (
|
|
|
Ok(len),
|
|
|
- Endpoint::Ip(Some(smoltcp::wire::IpEndpoint {
|
|
|
+ Endpoint::Ip(Some(wire::IpEndpoint {
|
|
|
addr: wire::IpAddress::Ipv4(packet.src_addr()),
|
|
|
port: 0,
|
|
|
})),
|
|
|
);
|
|
|
}
|
|
|
- Err(smoltcp::socket::raw::RecvError::Exhausted) => {
|
|
|
+ Err(raw::RecvError::Exhausted) => {
|
|
|
if !self.metadata.options.contains(SocketOptions::BLOCK) {
|
|
|
// 如果是非阻塞的socket,就返回错误
|
|
|
return (Err(SystemError::EAGAIN_OR_EWOULDBLOCK), Endpoint::Ip(None));
|
|
@@ -406,16 +129,16 @@ impl Socket for RawSocket {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn write(&self, buf: &[u8], to: Option<super::Endpoint>) -> Result<usize, SystemError> {
|
|
|
+ fn write(&self, buf: &[u8], to: Option<Endpoint>) -> Result<usize, SystemError> {
|
|
|
// 如果用户发送的数据包,包含IP头,则直接发送
|
|
|
if self.header_included {
|
|
|
let mut socket_set_guard = SOCKET_SET.lock_irqsave();
|
|
|
let socket = socket_set_guard.get_mut::<raw::Socket>(self.handle.0);
|
|
|
match socket.send_slice(buf) {
|
|
|
- Ok(_len) => {
|
|
|
+ Ok(_) => {
|
|
|
return Ok(buf.len());
|
|
|
}
|
|
|
- Err(smoltcp::socket::raw::SendError::BufferFull) => {
|
|
|
+ Err(raw::SendError::BufferFull) => {
|
|
|
return Err(SystemError::ENOBUFS);
|
|
|
}
|
|
|
}
|
|
@@ -431,7 +154,7 @@ impl Socket for RawSocket {
|
|
|
let iface = NET_DRIVERS.read_irqsave().get(&0).unwrap().clone();
|
|
|
|
|
|
// 构造IP头
|
|
|
- let ipv4_src_addr: Option<smoltcp::wire::Ipv4Address> =
|
|
|
+ let ipv4_src_addr: Option<wire::Ipv4Address> =
|
|
|
iface.inner_iface().lock().ipv4_addr();
|
|
|
if ipv4_src_addr.is_none() {
|
|
|
return Err(SystemError::ENETUNREACH);
|
|
@@ -481,15 +204,15 @@ impl Socket for RawSocket {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn connect(&mut self, _endpoint: super::Endpoint) -> Result<(), SystemError> {
|
|
|
- return Ok(());
|
|
|
+ fn connect(&mut self, _endpoint: Endpoint) -> Result<(), SystemError> {
|
|
|
+ Ok(())
|
|
|
}
|
|
|
|
|
|
fn metadata(&self) -> Result<SocketMetadata, SystemError> {
|
|
|
Ok(self.metadata.clone())
|
|
|
}
|
|
|
|
|
|
- fn box_clone(&self) -> alloc::boxed::Box<dyn Socket> {
|
|
|
+ fn box_clone(&self) -> Box<dyn Socket> {
|
|
|
return Box::new(self.clone());
|
|
|
}
|
|
|
|
|
@@ -511,27 +234,26 @@ pub struct UdpSocket {
|
|
|
impl UdpSocket {
|
|
|
/// 元数据的缓冲区的大小
|
|
|
pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024;
|
|
|
- /// 默认的发送缓冲区的大小 transmiss
|
|
|
- pub const DEFAULT_RX_BUF_SIZE: usize = 64 * 1024;
|
|
|
/// 默认的接收缓冲区的大小 receive
|
|
|
+ pub const DEFAULT_RX_BUF_SIZE: usize = 64 * 1024;
|
|
|
+ /// 默认的发送缓冲区的大小 transmiss
|
|
|
pub const DEFAULT_TX_BUF_SIZE: usize = 64 * 1024;
|
|
|
|
|
|
- /// @brief 创建一个原始的socket
|
|
|
+ /// @brief 创建一个udp的socket
|
|
|
///
|
|
|
- /// @param protocol 协议号
|
|
|
/// @param options socket的选项
|
|
|
///
|
|
|
- /// @return 返回创建的原始的socket
|
|
|
+ /// @return 返回创建的udp的socket
|
|
|
pub fn new(options: SocketOptions) -> Self {
|
|
|
- let tx_buffer = udp::PacketBuffer::new(
|
|
|
- vec![udp::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
|
|
|
- vec![0; Self::DEFAULT_TX_BUF_SIZE],
|
|
|
- );
|
|
|
let rx_buffer = udp::PacketBuffer::new(
|
|
|
vec![udp::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
|
|
|
vec![0; Self::DEFAULT_RX_BUF_SIZE],
|
|
|
);
|
|
|
- let socket = udp::Socket::new(tx_buffer, rx_buffer);
|
|
|
+ let tx_buffer = udp::PacketBuffer::new(
|
|
|
+ vec![udp::PacketMetadata::EMPTY; Self::DEFAULT_METADATA_BUF_SIZE],
|
|
|
+ vec![0; Self::DEFAULT_TX_BUF_SIZE],
|
|
|
+ );
|
|
|
+ let socket = udp::Socket::new(rx_buffer, tx_buffer);
|
|
|
|
|
|
// 把socket添加到socket集合中,并得到socket的句柄
|
|
|
let handle: Arc<GlobalSocketHandle> =
|
|
@@ -569,11 +291,19 @@ impl UdpSocket {
|
|
|
}
|
|
|
} else {
|
|
|
return Err(SystemError::EINVAL);
|
|
|
- };
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
impl Socket for UdpSocket {
|
|
|
+ fn as_any_ref(&self) -> &dyn core::any::Any {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ fn as_any_mut(&mut self) -> &mut dyn core::any::Any {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
/// @brief 在read函数执行之前,请先bind到本地的指定端口
|
|
|
fn read(&mut self, buf: &mut [u8]) -> (Result<usize, SystemError>, Endpoint) {
|
|
|
loop {
|
|
@@ -603,7 +333,7 @@ impl Socket for UdpSocket {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn write(&self, buf: &[u8], to: Option<super::Endpoint>) -> Result<usize, SystemError> {
|
|
|
+ fn write(&self, buf: &[u8], to: Option<Endpoint>) -> Result<usize, SystemError> {
|
|
|
// kdebug!("udp to send: {:?}, len={}", to, buf.len());
|
|
|
let remote_endpoint: &wire::IpEndpoint = {
|
|
|
if let Some(Endpoint::Ip(Some(ref endpoint))) = to {
|
|
@@ -627,11 +357,11 @@ impl Socket for UdpSocket {
|
|
|
// 远程remote endpoint使用什么协议,发送的时候使用的协议是一样的吧
|
|
|
// 否则就用 self.endpoint().addr.unwrap()
|
|
|
wire::IpAddress::Ipv4(_) => Endpoint::Ip(Some(wire::IpEndpoint::new(
|
|
|
- smoltcp::wire::IpAddress::Ipv4(wire::Ipv4Address::UNSPECIFIED),
|
|
|
+ wire::IpAddress::Ipv4(wire::Ipv4Address::UNSPECIFIED),
|
|
|
temp_port,
|
|
|
))),
|
|
|
wire::IpAddress::Ipv6(_) => Endpoint::Ip(Some(wire::IpEndpoint::new(
|
|
|
- smoltcp::wire::IpAddress::Ipv6(wire::Ipv6Address::UNSPECIFIED),
|
|
|
+ wire::IpAddress::Ipv6(wire::Ipv6Address::UNSPECIFIED),
|
|
|
temp_port,
|
|
|
))),
|
|
|
};
|
|
@@ -680,8 +410,7 @@ impl Socket for UdpSocket {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- /// @brief
|
|
|
- fn connect(&mut self, endpoint: super::Endpoint) -> Result<(), SystemError> {
|
|
|
+ fn connect(&mut self, endpoint: Endpoint) -> Result<(), SystemError> {
|
|
|
if let Endpoint::Ip(_) = endpoint {
|
|
|
self.remote_endpoint = Some(endpoint);
|
|
|
return Ok(());
|
|
@@ -699,11 +428,12 @@ impl Socket for UdpSocket {
|
|
|
) -> Result<usize, SystemError> {
|
|
|
todo!()
|
|
|
}
|
|
|
+
|
|
|
fn metadata(&self) -> Result<SocketMetadata, SystemError> {
|
|
|
Ok(self.metadata.clone())
|
|
|
}
|
|
|
|
|
|
- fn box_clone(&self) -> alloc::boxed::Box<dyn Socket> {
|
|
|
+ fn box_clone(&self) -> Box<dyn Socket> {
|
|
|
return Box::new(self.clone());
|
|
|
}
|
|
|
|
|
@@ -751,25 +481,24 @@ pub struct TcpSocket {
|
|
|
impl TcpSocket {
|
|
|
/// 元数据的缓冲区的大小
|
|
|
pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024;
|
|
|
- /// 默认的发送缓冲区的大小 transmiss
|
|
|
- pub const DEFAULT_RX_BUF_SIZE: usize = 512 * 1024;
|
|
|
/// 默认的接收缓冲区的大小 receive
|
|
|
+ pub const DEFAULT_RX_BUF_SIZE: usize = 512 * 1024;
|
|
|
+ /// 默认的发送缓冲区的大小 transmiss
|
|
|
pub const DEFAULT_TX_BUF_SIZE: usize = 512 * 1024;
|
|
|
|
|
|
/// TcpSocket的特殊事件,用于在事件等待队列上sleep
|
|
|
pub const CAN_CONNECT: u64 = 1u64 << 63;
|
|
|
pub const CAN_ACCPET: u64 = 1u64 << 62;
|
|
|
|
|
|
- /// @brief 创建一个原始的socket
|
|
|
+ /// @brief 创建一个tcp的socket
|
|
|
///
|
|
|
- /// @param protocol 协议号
|
|
|
/// @param options socket的选项
|
|
|
///
|
|
|
- /// @return 返回创建的原始的socket
|
|
|
+ /// @return 返回创建的tcp的socket
|
|
|
pub fn new(options: SocketOptions) -> Self {
|
|
|
- let tx_buffer = tcp::SocketBuffer::new(vec![0; Self::DEFAULT_TX_BUF_SIZE]);
|
|
|
let rx_buffer = tcp::SocketBuffer::new(vec![0; Self::DEFAULT_RX_BUF_SIZE]);
|
|
|
- let socket = tcp::Socket::new(tx_buffer, rx_buffer);
|
|
|
+ let tx_buffer = tcp::SocketBuffer::new(vec![0; Self::DEFAULT_TX_BUF_SIZE]);
|
|
|
+ let socket = tcp::Socket::new(rx_buffer, tx_buffer);
|
|
|
|
|
|
// 把socket添加到socket集合中,并得到socket的句柄
|
|
|
let handle: Arc<GlobalSocketHandle> =
|
|
@@ -792,8 +521,8 @@ impl TcpSocket {
|
|
|
}
|
|
|
fn do_listen(
|
|
|
&mut self,
|
|
|
- socket: &mut smoltcp::socket::tcp::Socket,
|
|
|
- local_endpoint: smoltcp::wire::IpEndpoint,
|
|
|
+ socket: &mut tcp::Socket,
|
|
|
+ local_endpoint: wire::IpEndpoint,
|
|
|
) -> Result<(), SystemError> {
|
|
|
let listen_result = if local_endpoint.addr.is_unspecified() {
|
|
|
// kdebug!("Tcp Socket Listen on port {}", local_endpoint.port);
|
|
@@ -819,6 +548,14 @@ impl TcpSocket {
|
|
|
}
|
|
|
|
|
|
impl Socket for TcpSocket {
|
|
|
+ fn as_any_ref(&self) -> &dyn core::any::Any {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ fn as_any_mut(&mut self) -> &mut dyn core::any::Any {
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
fn read(&mut self, buf: &mut [u8]) -> (Result<usize, SystemError>, Endpoint) {
|
|
|
if HANDLE_MAP
|
|
|
.read_irqsave()
|
|
@@ -888,7 +625,7 @@ impl Socket for TcpSocket {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fn write(&self, buf: &[u8], _to: Option<super::Endpoint>) -> Result<usize, SystemError> {
|
|
|
+ fn write(&self, buf: &[u8], _to: Option<Endpoint>) -> Result<usize, SystemError> {
|
|
|
if HANDLE_MAP
|
|
|
.read_irqsave()
|
|
|
.get(&self.socket_handle())
|
|
@@ -1080,8 +817,8 @@ impl Socket for TcpSocket {
|
|
|
|
|
|
let metadata = SocketMetadata::new(
|
|
|
SocketType::TcpSocket,
|
|
|
- Self::DEFAULT_RX_BUF_SIZE,
|
|
|
Self::DEFAULT_TX_BUF_SIZE,
|
|
|
+ Self::DEFAULT_RX_BUF_SIZE,
|
|
|
Self::DEFAULT_METADATA_BUF_SIZE,
|
|
|
self.metadata.options,
|
|
|
);
|
|
@@ -1145,7 +882,7 @@ impl Socket for TcpSocket {
|
|
|
Ok(self.metadata.clone())
|
|
|
}
|
|
|
|
|
|
- fn box_clone(&self) -> alloc::boxed::Box<dyn Socket> {
|
|
|
+ fn box_clone(&self) -> Box<dyn Socket> {
|
|
|
return Box::new(self.clone());
|
|
|
}
|
|
|
|
|
@@ -1154,328 +891,117 @@ impl Socket for TcpSocket {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/// @brief 地址族的枚举
|
|
|
-///
|
|
|
-/// 参考:https://code.dragonos.org.cn/xref/linux-5.19.10/include/linux/socket.h#180
|
|
|
-#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
|
|
-pub enum AddressFamily {
|
|
|
- /// AF_UNSPEC 表示地址族未指定
|
|
|
- Unspecified = 0,
|
|
|
- /// AF_UNIX 表示Unix域的socket (与AF_LOCAL相同)
|
|
|
- Unix = 1,
|
|
|
- /// AF_INET 表示IPv4的socket
|
|
|
- INet = 2,
|
|
|
- /// AF_AX25 表示AMPR AX.25的socket
|
|
|
- AX25 = 3,
|
|
|
- /// AF_IPX 表示IPX的socket
|
|
|
- IPX = 4,
|
|
|
- /// AF_APPLETALK 表示Appletalk的socket
|
|
|
- Appletalk = 5,
|
|
|
- /// AF_NETROM 表示AMPR NET/ROM的socket
|
|
|
- Netrom = 6,
|
|
|
- /// AF_BRIDGE 表示多协议桥接的socket
|
|
|
- Bridge = 7,
|
|
|
- /// AF_ATMPVC 表示ATM PVCs的socket
|
|
|
- Atmpvc = 8,
|
|
|
- /// AF_X25 表示X.25的socket
|
|
|
- X25 = 9,
|
|
|
- /// AF_INET6 表示IPv6的socket
|
|
|
- INet6 = 10,
|
|
|
- /// AF_ROSE 表示AMPR ROSE的socket
|
|
|
- Rose = 11,
|
|
|
- /// AF_DECnet Reserved for DECnet project
|
|
|
- Decnet = 12,
|
|
|
- /// AF_NETBEUI Reserved for 802.2LLC project
|
|
|
- Netbeui = 13,
|
|
|
- /// AF_SECURITY 表示Security callback的伪AF
|
|
|
- Security = 14,
|
|
|
- /// AF_KEY 表示Key management API
|
|
|
- Key = 15,
|
|
|
- /// AF_NETLINK 表示Netlink的socket
|
|
|
- Netlink = 16,
|
|
|
- /// AF_PACKET 表示Low level packet interface
|
|
|
- Packet = 17,
|
|
|
- /// AF_ASH 表示Ash
|
|
|
- Ash = 18,
|
|
|
- /// AF_ECONET 表示Acorn Econet
|
|
|
- Econet = 19,
|
|
|
- /// AF_ATMSVC 表示ATM SVCs
|
|
|
- Atmsvc = 20,
|
|
|
- /// AF_RDS 表示Reliable Datagram Sockets
|
|
|
- Rds = 21,
|
|
|
- /// AF_SNA 表示Linux SNA Project
|
|
|
- Sna = 22,
|
|
|
- /// AF_IRDA 表示IRDA sockets
|
|
|
- Irda = 23,
|
|
|
- /// AF_PPPOX 表示PPPoX sockets
|
|
|
- Pppox = 24,
|
|
|
- /// AF_WANPIPE 表示WANPIPE API sockets
|
|
|
- WanPipe = 25,
|
|
|
- /// AF_LLC 表示Linux LLC
|
|
|
- Llc = 26,
|
|
|
- /// AF_IB 表示Native InfiniBand address
|
|
|
- /// 介绍:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html-single/configuring_infiniband_and_rdma_networks/index#understanding-infiniband-and-rdma_configuring-infiniband-and-rdma-networks
|
|
|
- Ib = 27,
|
|
|
- /// AF_MPLS 表示MPLS
|
|
|
- Mpls = 28,
|
|
|
- /// AF_CAN 表示Controller Area Network
|
|
|
- Can = 29,
|
|
|
- /// AF_TIPC 表示TIPC sockets
|
|
|
- Tipc = 30,
|
|
|
- /// AF_BLUETOOTH 表示Bluetooth sockets
|
|
|
- Bluetooth = 31,
|
|
|
- /// AF_IUCV 表示IUCV sockets
|
|
|
- Iucv = 32,
|
|
|
- /// AF_RXRPC 表示RxRPC sockets
|
|
|
- Rxrpc = 33,
|
|
|
- /// AF_ISDN 表示mISDN sockets
|
|
|
- Isdn = 34,
|
|
|
- /// AF_PHONET 表示Phonet sockets
|
|
|
- Phonet = 35,
|
|
|
- /// AF_IEEE802154 表示IEEE 802.15.4 sockets
|
|
|
- Ieee802154 = 36,
|
|
|
- /// AF_CAIF 表示CAIF sockets
|
|
|
- Caif = 37,
|
|
|
- /// AF_ALG 表示Algorithm sockets
|
|
|
- Alg = 38,
|
|
|
- /// AF_NFC 表示NFC sockets
|
|
|
- Nfc = 39,
|
|
|
- /// AF_VSOCK 表示vSockets
|
|
|
- Vsock = 40,
|
|
|
- /// AF_KCM 表示Kernel Connection Multiplexor
|
|
|
- Kcm = 41,
|
|
|
- /// AF_QIPCRTR 表示Qualcomm IPC Router
|
|
|
- Qipcrtr = 42,
|
|
|
- /// AF_SMC 表示SMC-R sockets.
|
|
|
- /// reserve number for PF_SMC protocol family that reuses AF_INET address family
|
|
|
- Smc = 43,
|
|
|
- /// AF_XDP 表示XDP sockets
|
|
|
- Xdp = 44,
|
|
|
- /// AF_MCTP 表示Management Component Transport Protocol
|
|
|
- Mctp = 45,
|
|
|
- /// AF_MAX 表示最大的地址族
|
|
|
- Max = 46,
|
|
|
-}
|
|
|
-
|
|
|
-impl TryFrom<u16> for AddressFamily {
|
|
|
- type Error = SystemError;
|
|
|
- fn try_from(x: u16) -> Result<Self, Self::Error> {
|
|
|
- use num_traits::FromPrimitive;
|
|
|
- return <Self as FromPrimitive>::from_u16(x).ok_or_else(|| SystemError::EINVAL);
|
|
|
- }
|
|
|
+/// # 表示 seqpacket socket
|
|
|
+#[derive(Debug, Clone)]
|
|
|
+#[cast_to(Socket)]
|
|
|
+pub struct SeqpacketSocket {
|
|
|
+ metadata: SocketMetadata,
|
|
|
+ buffer: Arc<SpinLock<Vec<u8>>>,
|
|
|
+ peer_buffer: Option<Arc<SpinLock<Vec<u8>>>>,
|
|
|
}
|
|
|
|
|
|
-/// @brief posix套接字类型的枚举(这些值与linux内核中的值一致)
|
|
|
-#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
|
|
-pub enum PosixSocketType {
|
|
|
- Stream = 1,
|
|
|
- Datagram = 2,
|
|
|
- Raw = 3,
|
|
|
- Rdm = 4,
|
|
|
- SeqPacket = 5,
|
|
|
- Dccp = 6,
|
|
|
- Packet = 10,
|
|
|
-}
|
|
|
+impl SeqpacketSocket {
|
|
|
+ /// 默认的元数据缓冲区大小
|
|
|
+ pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024;
|
|
|
+ /// 默认的缓冲区大小
|
|
|
+ pub const DEFAULT_BUF_SIZE: usize = 64 * 1024;
|
|
|
|
|
|
-impl TryFrom<u8> for PosixSocketType {
|
|
|
- type Error = SystemError;
|
|
|
- fn try_from(x: u8) -> Result<Self, Self::Error> {
|
|
|
- use num_traits::FromPrimitive;
|
|
|
- return <Self as FromPrimitive>::from_u8(x).ok_or_else(|| SystemError::EINVAL);
|
|
|
- }
|
|
|
-}
|
|
|
+ /// # 创建一个seqpacket的socket
|
|
|
+ ///
|
|
|
+ /// ## 参数
|
|
|
+ /// - `options`: socket的选项
|
|
|
+ pub fn new(options: SocketOptions) -> Self {
|
|
|
+ let buffer = Vec::with_capacity(Self::DEFAULT_BUF_SIZE);
|
|
|
|
|
|
-/// @brief Socket在文件系统中的inode封装
|
|
|
-#[derive(Debug)]
|
|
|
-pub struct SocketInode(SpinLock<Box<dyn Socket>>);
|
|
|
+ let metadata = SocketMetadata::new(
|
|
|
+ SocketType::SeqpacketSocket,
|
|
|
+ Self::DEFAULT_BUF_SIZE,
|
|
|
+ 0,
|
|
|
+ Self::DEFAULT_METADATA_BUF_SIZE,
|
|
|
+ options,
|
|
|
+ );
|
|
|
|
|
|
-impl SocketInode {
|
|
|
- pub fn new(socket: Box<dyn Socket>) -> Arc<Self> {
|
|
|
- return Arc::new(Self(SpinLock::new(socket)));
|
|
|
+ return Self {
|
|
|
+ metadata,
|
|
|
+ buffer: Arc::new(SpinLock::new(buffer)),
|
|
|
+ peer_buffer: None,
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
- #[inline]
|
|
|
- pub fn inner(&self) -> SpinLockGuard<Box<dyn Socket>> {
|
|
|
- return self.0.lock();
|
|
|
+ fn buffer(&self) -> Arc<SpinLock<Vec<u8>>> {
|
|
|
+ self.buffer.clone()
|
|
|
}
|
|
|
|
|
|
- pub unsafe fn inner_no_preempt(&self) -> SpinLockGuard<Box<dyn Socket>> {
|
|
|
- return self.0.lock_no_preempt();
|
|
|
+ fn set_peer_buffer(&mut self, peer_buffer: Arc<SpinLock<Vec<u8>>>) {
|
|
|
+ self.peer_buffer = Some(peer_buffer);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl IndexNode for SocketInode {
|
|
|
- fn open(
|
|
|
- &self,
|
|
|
- _data: &mut crate::filesystem::vfs::FilePrivateData,
|
|
|
- _mode: &crate::filesystem::vfs::file::FileMode,
|
|
|
- ) -> Result<(), SystemError> {
|
|
|
- return Ok(());
|
|
|
- }
|
|
|
-
|
|
|
- fn close(
|
|
|
- &self,
|
|
|
- _data: &mut crate::filesystem::vfs::FilePrivateData,
|
|
|
- ) -> Result<(), SystemError> {
|
|
|
- let mut socket = self.0.lock_irqsave();
|
|
|
- if let Some(Endpoint::Ip(Some(ip))) = socket.endpoint() {
|
|
|
- PORT_MANAGER.unbind_port(socket.metadata().unwrap().socket_type, ip.port)?;
|
|
|
- }
|
|
|
-
|
|
|
- let _ = socket.clear_epoll();
|
|
|
-
|
|
|
- HANDLE_MAP
|
|
|
- .write_irqsave()
|
|
|
- .remove(&socket.socket_handle())
|
|
|
- .unwrap();
|
|
|
- return Ok(());
|
|
|
- }
|
|
|
-
|
|
|
- fn read_at(
|
|
|
- &self,
|
|
|
- _offset: usize,
|
|
|
- len: usize,
|
|
|
- buf: &mut [u8],
|
|
|
- _data: &mut crate::filesystem::vfs::FilePrivateData,
|
|
|
- ) -> Result<usize, SystemError> {
|
|
|
- return self.0.lock_no_preempt().read(&mut buf[0..len]).0;
|
|
|
- }
|
|
|
-
|
|
|
- fn write_at(
|
|
|
- &self,
|
|
|
- _offset: usize,
|
|
|
- len: usize,
|
|
|
- buf: &[u8],
|
|
|
- _data: &mut crate::filesystem::vfs::FilePrivateData,
|
|
|
- ) -> Result<usize, SystemError> {
|
|
|
- return self.0.lock_no_preempt().write(&buf[0..len], None);
|
|
|
- }
|
|
|
-
|
|
|
- fn poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError> {
|
|
|
- let events = self.0.lock_irqsave().poll();
|
|
|
- return Ok(events.bits() as usize);
|
|
|
- }
|
|
|
-
|
|
|
- fn fs(&self) -> alloc::sync::Arc<dyn crate::filesystem::vfs::FileSystem> {
|
|
|
- todo!()
|
|
|
- }
|
|
|
-
|
|
|
+impl Socket for SeqpacketSocket {
|
|
|
fn as_any_ref(&self) -> &dyn core::any::Any {
|
|
|
self
|
|
|
}
|
|
|
|
|
|
- fn list(&self) -> Result<Vec<alloc::string::String>, SystemError> {
|
|
|
- return Err(SystemError::ENOTDIR);
|
|
|
+ fn as_any_mut(&mut self) -> &mut dyn core::any::Any {
|
|
|
+ self
|
|
|
}
|
|
|
|
|
|
- fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
|
|
|
- let meta = Metadata {
|
|
|
- mode: ModeType::from_bits_truncate(0o755),
|
|
|
- file_type: FileType::Socket,
|
|
|
- ..Default::default()
|
|
|
- };
|
|
|
-
|
|
|
- return Ok(meta);
|
|
|
- }
|
|
|
+ fn read(&mut self, buf: &mut [u8]) -> (Result<usize, SystemError>, Endpoint) {
|
|
|
+ let buffer = self.buffer.lock_irqsave();
|
|
|
|
|
|
- fn resize(&self, _len: usize) -> Result<(), SystemError> {
|
|
|
- return Ok(());
|
|
|
- }
|
|
|
-}
|
|
|
+ let len = core::cmp::min(buf.len(), buffer.len());
|
|
|
+ buf[..len].copy_from_slice(&buffer[..len]);
|
|
|
|
|
|
-/// ### 为socket提供无锁的poll方法
|
|
|
-///
|
|
|
-/// 因为在网卡中断中,需要轮询socket的状态,如果使用socket文件或者其inode来poll
|
|
|
-/// 在当前的设计,会必然死锁,所以引用这一个设计来解决,提供无🔓的poll
|
|
|
-pub struct SocketPollMethod;
|
|
|
-
|
|
|
-impl SocketPollMethod {
|
|
|
- pub fn poll(socket: &socket::Socket, shutdown: ShutdownType) -> EPollEventType {
|
|
|
- match socket {
|
|
|
- socket::Socket::Raw(_) => todo!(),
|
|
|
- socket::Socket::Icmp(_) => todo!(),
|
|
|
- socket::Socket::Udp(udp) => Self::udp_poll(udp, shutdown),
|
|
|
- socket::Socket::Tcp(tcp) => Self::tcp_poll(tcp, shutdown),
|
|
|
- socket::Socket::Dhcpv4(_) => todo!(),
|
|
|
- socket::Socket::Dns(_) => todo!(),
|
|
|
- }
|
|
|
+ (Ok(len), Endpoint::Unused)
|
|
|
}
|
|
|
|
|
|
- pub fn tcp_poll(socket: &socket::tcp::Socket, shutdown: ShutdownType) -> EPollEventType {
|
|
|
- let mut events = EPollEventType::empty();
|
|
|
- if socket.is_listening() && socket.is_active() {
|
|
|
- events.insert(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM);
|
|
|
- return events;
|
|
|
- }
|
|
|
-
|
|
|
- // socket已经关闭
|
|
|
- if !socket.is_open() {
|
|
|
- events.insert(EPollEventType::EPOLLHUP)
|
|
|
- }
|
|
|
- if shutdown.contains(ShutdownType::RCV_SHUTDOWN) {
|
|
|
- events.insert(
|
|
|
- EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM | EPollEventType::EPOLLRDHUP,
|
|
|
- );
|
|
|
+ fn write(&self, buf: &[u8], _to: Option<Endpoint>) -> Result<usize, SystemError> {
|
|
|
+ if self.peer_buffer.is_none() {
|
|
|
+ kwarn!("SeqpacketSocket is now just for socketpair");
|
|
|
+ return Err(SystemError::ENOSYS);
|
|
|
}
|
|
|
|
|
|
- let state = socket.state();
|
|
|
- if state != State::SynSent && state != State::SynReceived {
|
|
|
- // socket有可读数据
|
|
|
- if socket.can_recv() {
|
|
|
- events.insert(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM);
|
|
|
- }
|
|
|
+ let binding = self.peer_buffer.clone().unwrap();
|
|
|
+ let mut peer_buffer = binding.lock_irqsave();
|
|
|
|
|
|
- if !(shutdown.contains(ShutdownType::SEND_SHUTDOWN)) {
|
|
|
- // 缓冲区可写
|
|
|
- if socket.send_queue() < socket.send_capacity() {
|
|
|
- events.insert(EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM);
|
|
|
- } else {
|
|
|
- // TODO:触发缓冲区已满的信号
|
|
|
- todo!("A signal that the buffer is full needs to be sent");
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 如果我们的socket关闭了SEND_SHUTDOWN,epoll事件就是EPOLLOUT
|
|
|
- events.insert(EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM);
|
|
|
- }
|
|
|
- } else if state == State::SynSent {
|
|
|
- events.insert(EPollEventType::EPOLLOUT | EPollEventType::EPOLLWRNORM);
|
|
|
+ let len = buf.len();
|
|
|
+ if peer_buffer.capacity() - peer_buffer.len() < len {
|
|
|
+ return Err(SystemError::ENOBUFS);
|
|
|
}
|
|
|
+ peer_buffer[..len].copy_from_slice(buf);
|
|
|
|
|
|
- // socket发生错误
|
|
|
- if !socket.is_active() {
|
|
|
- events.insert(EPollEventType::EPOLLERR);
|
|
|
- }
|
|
|
+ Ok(len)
|
|
|
+ }
|
|
|
|
|
|
- events
|
|
|
+ fn socketpair_ops(&self) -> Option<&'static dyn SocketpairOps> {
|
|
|
+ Some(&SeqpacketSocketpairOps)
|
|
|
}
|
|
|
|
|
|
- pub fn udp_poll(socket: &socket::udp::Socket, shutdown: ShutdownType) -> EPollEventType {
|
|
|
- let mut event = EPollEventType::empty();
|
|
|
+ fn metadata(&self) -> Result<SocketMetadata, SystemError> {
|
|
|
+ Ok(self.metadata.clone())
|
|
|
+ }
|
|
|
|
|
|
- if shutdown.contains(ShutdownType::RCV_SHUTDOWN) {
|
|
|
- event.insert(
|
|
|
- EPollEventType::EPOLLRDHUP | EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM,
|
|
|
- );
|
|
|
- }
|
|
|
- if shutdown.contains(ShutdownType::SHUTDOWN_MASK) {
|
|
|
- event.insert(EPollEventType::EPOLLHUP);
|
|
|
- }
|
|
|
+ fn box_clone(&self) -> Box<dyn Socket> {
|
|
|
+ Box::new(self.clone())
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- if socket.can_recv() {
|
|
|
- event.insert(EPollEventType::EPOLLIN | EPollEventType::EPOLLRDNORM);
|
|
|
- }
|
|
|
+struct SeqpacketSocketpairOps;
|
|
|
|
|
|
- if socket.can_send() {
|
|
|
- event.insert(
|
|
|
- EPollEventType::EPOLLOUT
|
|
|
- | EPollEventType::EPOLLWRNORM
|
|
|
- | EPollEventType::EPOLLWRBAND,
|
|
|
- );
|
|
|
- } else {
|
|
|
- // TODO: 缓冲区空间不够,需要使用信号处理
|
|
|
- todo!()
|
|
|
- }
|
|
|
+impl SocketpairOps for SeqpacketSocketpairOps {
|
|
|
+ fn socketpair(&self, socket0: &mut Box<dyn Socket>, socket1: &mut Box<dyn Socket>) {
|
|
|
+ let pair0 = socket0
|
|
|
+ .as_mut()
|
|
|
+ .as_any_mut()
|
|
|
+ .downcast_mut::<SeqpacketSocket>()
|
|
|
+ .unwrap();
|
|
|
|
|
|
- return event;
|
|
|
+ let pair1 = socket1
|
|
|
+ .as_mut()
|
|
|
+ .as_any_mut()
|
|
|
+ .downcast_mut::<SeqpacketSocket>()
|
|
|
+ .unwrap();
|
|
|
+ pair0.set_peer_buffer(pair1.buffer());
|
|
|
+ pair1.set_peer_buffer(pair0.buffer());
|
|
|
}
|
|
|
}
|