mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-22 15:23:23 +00:00
重新组织代码分布
This commit is contained in:
@ -145,99 +145,3 @@ pub fn poll_ifaces() {
|
|||||||
iface.poll();
|
iface.poll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// 对ifaces进行轮询,最多对SOCKET_SET尝试times次加锁。
|
|
||||||
// ///
|
|
||||||
// /// @return 轮询成功,返回Ok(())
|
|
||||||
// /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
|
|
||||||
// /// @return 没有网卡,返回SystemError::ENODEV
|
|
||||||
// pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
|
|
||||||
// let mut i = 0;
|
|
||||||
// while i < times {
|
|
||||||
// let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn Iface>>> =
|
|
||||||
// NET_DEVICES.read_irqsave();
|
|
||||||
// if guard.len() == 0 {
|
|
||||||
// warn!("poll_ifaces: No net driver found!");
|
|
||||||
// // 没有网卡,返回错误
|
|
||||||
// return Err(SystemError::ENODEV);
|
|
||||||
// }
|
|
||||||
// for (_, iface) in guard.iter() {
|
|
||||||
// iface.poll();
|
|
||||||
// }
|
|
||||||
// return Ok(());
|
|
||||||
// }
|
|
||||||
// // 尝试次数用完,返回错误
|
|
||||||
// return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// 对ifaces进行轮询,最多对SOCKET_SET尝试一次加锁。
|
|
||||||
// ///
|
|
||||||
// /// @return 轮询成功,返回Ok(())
|
|
||||||
// /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
|
|
||||||
// /// @return 没有网卡,返回SystemError::ENODEV
|
|
||||||
// pub fn poll_ifaces_try_lock_onetime() -> Result<(), SystemError> {
|
|
||||||
// let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn Iface>>> = NET_DEVICES.read_irqsave();
|
|
||||||
// if guard.len() == 0 {
|
|
||||||
// warn!("poll_ifaces: No net driver found!");
|
|
||||||
// // 没有网卡,返回错误
|
|
||||||
// return Err(SystemError::ENODEV);
|
|
||||||
// }
|
|
||||||
// for (_, iface) in guard.iter() {
|
|
||||||
// let _ = iface.poll();
|
|
||||||
// }
|
|
||||||
// send_event()?;
|
|
||||||
// return Ok(());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// ### 处理轮询后的事件
|
|
||||||
// fn send_event() -> Result<(), SystemError> {
|
|
||||||
// for (handle, socket_type) in .lock().iter() {
|
|
||||||
|
|
||||||
// let global_handle = GlobalSocketHandle::new_smoltcp_handle(handle);
|
|
||||||
|
|
||||||
// let handle_guard = HANDLE_MAP.read_irqsave();
|
|
||||||
// let item: Option<&super::socket::SocketHandleItem> = handle_guard.get(&global_handle);
|
|
||||||
// if item.is_none() {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let handle_item = item.unwrap();
|
|
||||||
// let posix_item = handle_item.posix_item();
|
|
||||||
// if posix_item.is_none() {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// let posix_item = posix_item.unwrap();
|
|
||||||
|
|
||||||
// // 获取socket上的事件
|
|
||||||
// let mut events = SocketPollMethod::poll(socket_type, handle_item).bits() as u64;
|
|
||||||
|
|
||||||
// // 分发到相应类型socket处理
|
|
||||||
// match socket_type {
|
|
||||||
// smoltcp::socket::Socket::Raw(_) | smoltcp::socket::Socket::Udp(_) => {
|
|
||||||
// posix_item.wakeup_any(events);
|
|
||||||
// }
|
|
||||||
// smoltcp::socket::Socket::Icmp(_) => unimplemented!("Icmp socket hasn't unimplemented"),
|
|
||||||
// smoltcp::socket::Socket::Tcp(inner_socket) => {
|
|
||||||
// if inner_socket.is_active() {
|
|
||||||
// events |= TcpSocket::CAN_ACCPET;
|
|
||||||
// }
|
|
||||||
// if inner_socket.state() == smoltcp::socket::tcp::State::Established {
|
|
||||||
// events |= TcpSocket::CAN_CONNECT;
|
|
||||||
// }
|
|
||||||
// if inner_socket.state() == smoltcp::socket::tcp::State::CloseWait {
|
|
||||||
// events |= EPollEventType::EPOLLHUP.bits() as u64;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// posix_item.wakeup_any(events);
|
|
||||||
// }
|
|
||||||
// smoltcp::socket::Socket::Dhcpv4(_) => {}
|
|
||||||
// smoltcp::socket::Socket::Dns(_) => unimplemented!("Dns socket hasn't unimplemented"),
|
|
||||||
// }
|
|
||||||
// EventPoll::wakeup_epoll(
|
|
||||||
// &posix_item.epitems,
|
|
||||||
// EPollEventType::from_bits_truncate(events as u32),
|
|
||||||
// )?;
|
|
||||||
// drop(handle_guard);
|
|
||||||
// }
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
@ -60,7 +60,7 @@ pub trait Socket: Sync + Send + Debug + Any {
|
|||||||
/// 对应于 Posix `getsockopt` ,获取socket选项
|
/// 对应于 Posix `getsockopt` ,获取socket选项
|
||||||
fn get_option(
|
fn get_option(
|
||||||
&self,
|
&self,
|
||||||
level: OptionsLevel,
|
level: OptionLevel,
|
||||||
name: usize,
|
name: usize,
|
||||||
value: &mut [u8],
|
value: &mut [u8],
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
@ -122,7 +122,7 @@ pub trait Socket: Sync + Send + Debug + Any {
|
|||||||
/// - value 选项的值
|
/// - value 选项的值
|
||||||
/// ## Reference
|
/// ## Reference
|
||||||
/// https://code.dragonos.org.cn/s?refs=sk_setsockopt&project=linux-6.6.21
|
/// https://code.dragonos.org.cn/s?refs=sk_setsockopt&project=linux-6.6.21
|
||||||
fn set_option(&self, level: OptionsLevel, name: usize, val: &[u8]) -> Result<(), SystemError> {
|
fn set_option(&self, level: OptionLevel, name: usize, val: &[u8]) -> Result<(), SystemError> {
|
||||||
log::warn!("setsockopt is not implemented");
|
log::warn!("setsockopt is not implemented");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
// pub mod poll_unit;
|
// pub mod poll_unit;
|
||||||
mod epoll_items;
|
mod epoll_items;
|
||||||
pub mod shutdown;
|
|
||||||
|
|
||||||
|
pub mod shutdown;
|
||||||
pub use epoll_items::EPollItems;
|
pub use epoll_items::EPollItems;
|
||||||
#[allow(dead_code)]
|
|
||||||
pub use shutdown::Shutdown;
|
|
||||||
|
|
||||||
// /// @brief 在trait Socket的metadata函数中返回该结构体供外部使用
|
// /// @brief 在trait Socket的metadata函数中返回该结构体供外部使用
|
||||||
// #[derive(Debug, Clone)]
|
// #[derive(Debug, Clone)]
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
// pub const SOL_SOCKET: u8 = 1,
|
|
||||||
// bitflags::bitflags! {
|
|
||||||
// pub struct OptionsLevel: u32 {
|
|
||||||
// const IP = 0,
|
|
||||||
// // const SOL_ICMP = 1, // No-no-no! Due to Linux :-) we cannot
|
|
||||||
// const SOCKET = 1,
|
|
||||||
// const TCP = 6,
|
|
||||||
// const UDP = 17,
|
|
||||||
// const IPV6 = 41,
|
|
||||||
// const ICMPV6 = 58,
|
|
||||||
// const SCTP = 132,
|
|
||||||
// const UDPLITE = 136, // UDP-Lite (RFC 3828)
|
|
||||||
// const RAW = 255,
|
|
||||||
// const IPX = 256,
|
|
||||||
// const AX25 = 257,
|
|
||||||
// const ATALK = 258,
|
|
||||||
// const NETROM = 259,
|
|
||||||
// const ROSE = 260,
|
|
||||||
// const DECNET = 261,
|
|
||||||
// const X25 = 262,
|
|
||||||
// const PACKET = 263,
|
|
||||||
// const ATM = 264, // ATM layer (cell level)
|
|
||||||
// const AAL = 265, // ATM Adaption Layer (packet level)
|
|
||||||
// const IRDA = 266,
|
|
||||||
// const NETBEUI = 267,
|
|
||||||
// const LLC = 268,
|
|
||||||
// const DCCP = 269,
|
|
||||||
// const NETLINK = 270,
|
|
||||||
// const TIPC = 271,
|
|
||||||
// const RXRPC = 272,
|
|
||||||
// const PPPOL2TP = 273,
|
|
||||||
// const BLUETOOTH = 274,
|
|
||||||
// const PNPIPE = 275,
|
|
||||||
// const RDS = 276,
|
|
||||||
// const IUCV = 277,
|
|
||||||
// const CAIF = 278,
|
|
||||||
// const ALG = 279,
|
|
||||||
// const NFC = 280,
|
|
||||||
// const KCM = 281,
|
|
||||||
// const TLS = 282,
|
|
||||||
// const XDP = 283,
|
|
||||||
// const MPTCP = 284,
|
|
||||||
// const MCTP = 285,
|
|
||||||
// const SMC = 286,
|
|
||||||
// const VSOCK = 287,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// # SOL (Socket Option Level)
|
|
||||||
/// Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx
|
|
||||||
/// ## Reference
|
|
||||||
/// - [Setsockoptions(2) level](https://code.dragonos.org.cn/xref/linux-6.6.21/include/linux/socket.h#345)
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum OptionsLevel {
|
|
||||||
IP = 0,
|
|
||||||
SOCKET = 1,
|
|
||||||
// ICMP = 1, No-no-no! Due to Linux :-) we cannot
|
|
||||||
TCP = 6,
|
|
||||||
UDP = 17,
|
|
||||||
IPV6 = 41,
|
|
||||||
ICMPV6 = 58,
|
|
||||||
SCTP = 132,
|
|
||||||
UDPLITE = 136, // UDP-Lite (RFC 3828)
|
|
||||||
RAW = 255,
|
|
||||||
IPX = 256,
|
|
||||||
AX25 = 257,
|
|
||||||
ATALK = 258,
|
|
||||||
NETROM = 259,
|
|
||||||
ROSE = 260,
|
|
||||||
DECNET = 261,
|
|
||||||
X25 = 262,
|
|
||||||
PACKET = 263,
|
|
||||||
ATM = 264, // ATM layer (cell level)
|
|
||||||
AAL = 265, // ATM Adaption Layer (packet level)
|
|
||||||
IRDA = 266,
|
|
||||||
NETBEUI = 267,
|
|
||||||
LLC = 268,
|
|
||||||
DCCP = 269,
|
|
||||||
NETLINK = 270,
|
|
||||||
TIPC = 271,
|
|
||||||
RXRPC = 272,
|
|
||||||
PPPOL2TP = 273,
|
|
||||||
BLUETOOTH = 274,
|
|
||||||
PNPIPE = 275,
|
|
||||||
RDS = 276,
|
|
||||||
IUCV = 277,
|
|
||||||
CAIF = 278,
|
|
||||||
ALG = 279,
|
|
||||||
NFC = 280,
|
|
||||||
KCM = 281,
|
|
||||||
TLS = 282,
|
|
||||||
XDP = 283,
|
|
||||||
MPTCP = 284,
|
|
||||||
MCTP = 285,
|
|
||||||
SMC = 286,
|
|
||||||
VSOCK = 287,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<u32> for OptionsLevel {
|
|
||||||
type Error = system_error::SystemError;
|
|
||||||
|
|
||||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
|
||||||
match <Self as num_traits::FromPrimitive>::from_u32(value) {
|
|
||||||
Some(p) => Ok(p),
|
|
||||||
None => Err(system_error::SystemError::EPROTONOSUPPORT),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<OptionsLevel> for u32 {
|
|
||||||
fn from(value: OptionsLevel) -> Self {
|
|
||||||
<OptionsLevel as num_traits::ToPrimitive>::to_u32(&value).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,133 +0,0 @@
|
|||||||
// bitflags! {
|
|
||||||
// // #[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
|
||||||
// pub struct Options: u32 {
|
|
||||||
// const DEBUG = 1;
|
|
||||||
// const REUSEADDR = 2;
|
|
||||||
// const TYPE = 3;
|
|
||||||
// const ERROR = 4;
|
|
||||||
// const DONTROUTE = 5;
|
|
||||||
// const BROADCAST = 6;
|
|
||||||
// const SNDBUF = 7;
|
|
||||||
// const RCVBUF = 8;
|
|
||||||
// const SNDBUFFORCE = 32;
|
|
||||||
// const RCVBUFFORCE = 33;
|
|
||||||
// const KEEPALIVE = 9;
|
|
||||||
// const OOBINLINE = 10;
|
|
||||||
// const NO_CHECK = 11;
|
|
||||||
// const PRIORITY = 12;
|
|
||||||
// const LINGER = 13;
|
|
||||||
// const BSDCOMPAT = 14;
|
|
||||||
// const REUSEPORT = 15;
|
|
||||||
// const PASSCRED = 16;
|
|
||||||
// const PEERCRED = 17;
|
|
||||||
// const RCVLOWAT = 18;
|
|
||||||
// const SNDLOWAT = 19;
|
|
||||||
// const RCVTIMEO_OLD = 20;
|
|
||||||
// const SNDTIMEO_OLD = 21;
|
|
||||||
//
|
|
||||||
// const SECURITY_AUTHENTICATION = 22;
|
|
||||||
// const SECURITY_ENCRYPTION_TRANSPORT = 23;
|
|
||||||
// const SECURITY_ENCRYPTION_NETWORK = 24;
|
|
||||||
//
|
|
||||||
// const BINDTODEVICE = 25;
|
|
||||||
//
|
|
||||||
// /// 与GET_FILTER相同
|
|
||||||
// const ATTACH_FILTER = 26;
|
|
||||||
// const DETACH_FILTER = 27;
|
|
||||||
//
|
|
||||||
// const PEERNAME = 28;
|
|
||||||
//
|
|
||||||
// const ACCEPTCONN = 30;
|
|
||||||
//
|
|
||||||
// const PEERSEC = 31;
|
|
||||||
// const PASSSEC = 34;
|
|
||||||
//
|
|
||||||
// const MARK = 36;
|
|
||||||
//
|
|
||||||
// const PROTOCOL = 38;
|
|
||||||
// const DOMAIN = 39;
|
|
||||||
//
|
|
||||||
// const RXQ_OVFL = 40;
|
|
||||||
//
|
|
||||||
// /// 与SCM_WIFI_STATUS相同
|
|
||||||
// const WIFI_STATUS = 41;
|
|
||||||
// const PEEK_OFF = 42;
|
|
||||||
//
|
|
||||||
// /* Instruct lower device to use last 4-bytes of skb data as FCS */
|
|
||||||
// const NOFCS = 43;
|
|
||||||
//
|
|
||||||
// const LOCK_FILTER = 44;
|
|
||||||
// const SELECT_ERR_QUEUE = 45;
|
|
||||||
// const BUSY_POLL = 46;
|
|
||||||
// const MAX_PACING_RATE = 47;
|
|
||||||
// const BPF_EXTENSIONS = 48;
|
|
||||||
// const INCOMING_CPU = 49;
|
|
||||||
// const ATTACH_BPF = 50;
|
|
||||||
// // DETACH_BPF = DETACH_FILTER;
|
|
||||||
// const ATTACH_REUSEPORT_CBPF = 51;
|
|
||||||
// const ATTACH_REUSEPORT_EBPF = 52;
|
|
||||||
//
|
|
||||||
// const CNX_ADVICE = 53;
|
|
||||||
// const SCM_TIMESTAMPING_OPT_STATS = 54;
|
|
||||||
// const MEMINFO = 55;
|
|
||||||
// const INCOMING_NAPI_ID = 56;
|
|
||||||
// const COOKIE = 57;
|
|
||||||
// const SCM_TIMESTAMPING_PKTINFO = 58;
|
|
||||||
// const PEERGROUPS = 59;
|
|
||||||
// const ZEROCOPY = 60;
|
|
||||||
// /// 与SCM_TXTIME相同
|
|
||||||
// const TXTIME = 61;
|
|
||||||
//
|
|
||||||
// const BINDTOIFINDEX = 62;
|
|
||||||
//
|
|
||||||
// const TIMESTAMP_OLD = 29;
|
|
||||||
// const TIMESTAMPNS_OLD = 35;
|
|
||||||
// const TIMESTAMPING_OLD = 37;
|
|
||||||
// const TIMESTAMP_NEW = 63;
|
|
||||||
// const TIMESTAMPNS_NEW = 64;
|
|
||||||
// const TIMESTAMPING_NEW = 65;
|
|
||||||
//
|
|
||||||
// const RCVTIMEO_NEW = 66;
|
|
||||||
// const SNDTIMEO_NEW = 67;
|
|
||||||
//
|
|
||||||
// const DETACH_REUSEPORT_BPF = 68;
|
|
||||||
//
|
|
||||||
// const PREFER_BUSY_POLL = 69;
|
|
||||||
// const BUSY_POLL_BUDGET = 70;
|
|
||||||
//
|
|
||||||
// const NETNS_COOKIE = 71;
|
|
||||||
// const BUF_LOCK = 72;
|
|
||||||
// const RESERVE_MEM = 73;
|
|
||||||
// const TXREHASH = 74;
|
|
||||||
// const RCVMARK = 75;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// bitflags::bitflags! {
|
|
||||||
// pub struct Level: i32 {
|
|
||||||
// const SOL_SOCKET = 1;
|
|
||||||
// const IPPROTO_IP = super::ip::Protocol::IP.bits();
|
|
||||||
// const IPPROTO_IPV6 = super::ip::Protocol::IPv6.bits();
|
|
||||||
// const IPPROTO_TCP = super::ip::Protocol::TCP.bits();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// bitflags! {
|
|
||||||
// /// @brief socket的选项
|
|
||||||
// #[derive(Default)]
|
|
||||||
// pub struct Options: u32 {
|
|
||||||
// /// 是否阻塞
|
|
||||||
// const BLOCK = 1 << 0;
|
|
||||||
// /// 是否允许广播
|
|
||||||
// const BROADCAST = 1 << 1;
|
|
||||||
// /// 是否允许多播
|
|
||||||
// const MULTICAST = 1 << 2;
|
|
||||||
// /// 是否允许重用地址
|
|
||||||
// const REUSEADDR = 1 << 3;
|
|
||||||
// /// 是否允许重用端口
|
|
||||||
// const REUSEPORT = 1 << 4;
|
|
||||||
// }
|
|
||||||
// }
|
|
12
kernel/src/net/socket/definition/mod.rs
Normal file
12
kernel/src/net/socket/definition/mod.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// socket definitions
|
||||||
|
mod option;
|
||||||
|
mod option_level;
|
||||||
|
mod msg_flag;
|
||||||
|
mod types;
|
||||||
|
|
||||||
|
pub use option::Options; // Socket options SO_*
|
||||||
|
pub use option_level::OptionLevel; // Socket options level SOL_*
|
||||||
|
pub use msg_flag::MessageFlag; // Socket message flags MSG_*
|
||||||
|
pub use types::Type; // Socket types SOCK_*
|
||||||
|
|
||||||
|
|
67
kernel/src/net/socket/definition/option_level.rs
Normal file
67
kernel/src/net/socket/definition/option_level.rs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/// # SOL (Socket Option Level)
|
||||||
|
/// Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx
|
||||||
|
/// ## Reference
|
||||||
|
/// - [Setsockoptions(2) level](https://code.dragonos.org.cn/xref/linux-6.6.21/include/linux/socket.h#345)
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
pub enum OptionLevel {
|
||||||
|
IP = 0,
|
||||||
|
SOCKET = 1,
|
||||||
|
// ICMP = 1, No-no-no! Due to Linux :-) we cannot
|
||||||
|
TCP = 6,
|
||||||
|
UDP = 17,
|
||||||
|
IPV6 = 41,
|
||||||
|
ICMPV6 = 58,
|
||||||
|
SCTP = 132,
|
||||||
|
UDPLITE = 136, // UDP-Lite (RFC 3828)
|
||||||
|
RAW = 255,
|
||||||
|
IPX = 256,
|
||||||
|
AX25 = 257,
|
||||||
|
ATALK = 258,
|
||||||
|
NETROM = 259,
|
||||||
|
ROSE = 260,
|
||||||
|
DECNET = 261,
|
||||||
|
X25 = 262,
|
||||||
|
PACKET = 263,
|
||||||
|
ATM = 264, // ATM layer (cell level)
|
||||||
|
AAL = 265, // ATM Adaption Layer (packet level)
|
||||||
|
IRDA = 266,
|
||||||
|
NETBEUI = 267,
|
||||||
|
LLC = 268,
|
||||||
|
DCCP = 269,
|
||||||
|
NETLINK = 270,
|
||||||
|
TIPC = 271,
|
||||||
|
RXRPC = 272,
|
||||||
|
PPPOL2TP = 273,
|
||||||
|
BLUETOOTH = 274,
|
||||||
|
PNPIPE = 275,
|
||||||
|
RDS = 276,
|
||||||
|
IUCV = 277,
|
||||||
|
CAIF = 278,
|
||||||
|
ALG = 279,
|
||||||
|
NFC = 280,
|
||||||
|
KCM = 281,
|
||||||
|
TLS = 282,
|
||||||
|
XDP = 283,
|
||||||
|
MPTCP = 284,
|
||||||
|
MCTP = 285,
|
||||||
|
SMC = 286,
|
||||||
|
VSOCK = 287,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<u32> for OptionLevel {
|
||||||
|
type Error = system_error::SystemError;
|
||||||
|
|
||||||
|
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||||
|
match <Self as num_traits::FromPrimitive>::from_u32(value) {
|
||||||
|
Some(p) => Ok(p),
|
||||||
|
None => Err(system_error::SystemError::EPROTONOSUPPORT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OptionLevel> for u32 {
|
||||||
|
fn from(value: OptionLevel) -> Self {
|
||||||
|
<OptionLevel as num_traits::ToPrimitive>::to_u32(&value).unwrap()
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,3 @@
|
|||||||
mod option;
|
|
||||||
pub use option::Options;
|
|
||||||
|
|
||||||
mod option_level;
|
|
||||||
pub use option_level::OptionsLevel;
|
|
||||||
|
|
||||||
mod msg_flag;
|
|
||||||
pub use msg_flag::MessageFlag;
|
|
||||||
|
|
||||||
mod ipproto;
|
|
||||||
pub use ipproto::IPProtocol;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Stream = 1,
|
Stream = 1,
|
@ -1,4 +1,4 @@
|
|||||||
const SOL_SOCKET: u16 = 1;
|
pub const SOL_SOCKET: u16 = 1;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||||
pub enum IPProtocol {
|
pub enum IPProtocol {
|
@ -1,6 +1,4 @@
|
|||||||
use alloc::sync::Arc;
|
|
||||||
use smoltcp;
|
use smoltcp;
|
||||||
use system_error::SystemError::{self, *};
|
|
||||||
|
|
||||||
// pub mod raw;
|
// pub mod raw;
|
||||||
// pub mod icmp;
|
// pub mod icmp;
|
||||||
@ -16,8 +14,6 @@ pub use datagram::UdpSocket;
|
|||||||
pub use stream::TcpSocket;
|
pub use stream::TcpSocket;
|
||||||
pub use syscall::Inet;
|
pub use syscall::Inet;
|
||||||
|
|
||||||
use crate::filesystem::vfs::IndexNode;
|
|
||||||
|
|
||||||
use super::Socket;
|
use super::Socket;
|
||||||
|
|
||||||
use smoltcp::wire::*;
|
use smoltcp::wire::*;
|
||||||
@ -85,66 +81,3 @@ pub trait InetSocket: Socket {
|
|||||||
// todo!()
|
// todo!()
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub trait Socket: FileLike + Send + Sync {
|
|
||||||
// /// Assign the address specified by socket_addr to the socket
|
|
||||||
// fn bind(&self, _socket_addr: SocketAddr) -> Result<()> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "bind() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Build connection for a given address
|
|
||||||
// fn connect(&self, _socket_addr: SocketAddr) -> Result<()> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "connect() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Listen for connections on a socket
|
|
||||||
// fn listen(&self, _backlog: usize) -> Result<()> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "listen() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Accept a connection on a socket
|
|
||||||
// fn accept(&self) -> Result<(Arc<dyn FileLike>, SocketAddr)> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "accept() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Shut down part of a full-duplex connection
|
|
||||||
// fn shutdown(&self, _cmd: SockShutdownCmd) -> Result<()> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "shutdown() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Get address of this socket.
|
|
||||||
// fn addr(&self) -> Result<SocketAddr> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "getsockname() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Get address of peer socket
|
|
||||||
// fn peer_addr(&self) -> Result<SocketAddr> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "getpeername() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Get options on the socket. The resulted option will put in the `option` parameter, if
|
|
||||||
// /// this method returns success.
|
|
||||||
// fn get_option(&self, _option: &mut dyn SocketOption) -> Result<()> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "getsockopt() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Set options on the socket.
|
|
||||||
// fn set_option(&self, _option: &dyn SocketOption) -> Result<()> {
|
|
||||||
// return_errno_with_message!(Errno::EOPNOTSUPP, "setsockopt() is not supported");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Sends a message on a socket.
|
|
||||||
// fn sendmsg(
|
|
||||||
// &self,
|
|
||||||
// io_vecs: &[IoVec],
|
|
||||||
// message_header: MessageHeader,
|
|
||||||
// flags: SendRecvFlags,
|
|
||||||
// ) -> Result<usize>;
|
|
||||||
|
|
||||||
// /// Receives a message from a socket.
|
|
||||||
// ///
|
|
||||||
// /// If successful, the `io_vecs` buffer will be filled with the received content.
|
|
||||||
// /// This method returns the length of the received message,
|
|
||||||
// /// and the message header.
|
|
||||||
// fn recvmsg(&self, io_vecs: &[IoVec], flags: SendRecvFlags) -> Result<(usize, MessageHeader)>;
|
|
||||||
// }
|
|
||||||
|
@ -10,9 +10,12 @@ use crate::sched::SchedMode;
|
|||||||
use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT};
|
use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT};
|
||||||
use smoltcp;
|
use smoltcp;
|
||||||
|
|
||||||
pub mod inner;
|
mod inner;
|
||||||
use inner::*;
|
use inner::*;
|
||||||
|
|
||||||
|
mod option;
|
||||||
|
pub use option::Options as TcpOption;
|
||||||
|
|
||||||
type EP = EPollEventType;
|
type EP = EPollEventType;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TcpSocket {
|
pub struct TcpSocket {
|
||||||
|
90
kernel/src/net/socket/inet/stream/option.rs
Normal file
90
kernel/src/net/socket/inet/stream/option.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
use num_traits::{FromPrimitive, ToPrimitive};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
||||||
|
pub enum Options {
|
||||||
|
/// 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 Options {
|
||||||
|
type Error = system_error::SystemError;
|
||||||
|
|
||||||
|
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
||||||
|
match <Self as FromPrimitive>::from_i32(value) {
|
||||||
|
Some(p) => Ok(p),
|
||||||
|
None => Err(Self::Error::EINVAL),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Options> for i32 {
|
||||||
|
fn from(val: Options) -> Self {
|
||||||
|
<Options as ToPrimitive>::to_i32(&val).unwrap()
|
||||||
|
}
|
||||||
|
}
|
@ -51,7 +51,6 @@ impl IndexNode for Inode {
|
|||||||
&self,
|
&self,
|
||||||
private_data: &crate::filesystem::vfs::FilePrivateData,
|
private_data: &crate::filesystem::vfs::FilePrivateData,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
// let _ = private_data;
|
|
||||||
Ok(self.inner.poll())
|
Ok(self.inner.poll())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +104,7 @@ impl Inode {
|
|||||||
|
|
||||||
pub fn set_option(
|
pub fn set_option(
|
||||||
&self,
|
&self,
|
||||||
level: OptionsLevel,
|
level: OptionLevel,
|
||||||
name: usize,
|
name: usize,
|
||||||
value: &[u8],
|
value: &[u8],
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
@ -114,7 +113,7 @@ impl Inode {
|
|||||||
|
|
||||||
pub fn get_option(
|
pub fn get_option(
|
||||||
&self,
|
&self,
|
||||||
level: OptionsLevel,
|
level: OptionLevel,
|
||||||
name: usize,
|
name: usize,
|
||||||
value: &mut [u8],
|
value: &mut [u8],
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
mod base;
|
mod base;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod common;
|
mod common;
|
||||||
mod define;
|
mod definition;
|
||||||
mod endpoint;
|
mod endpoint;
|
||||||
mod family;
|
mod family;
|
||||||
pub mod inet;
|
pub mod inet;
|
||||||
@ -18,7 +18,7 @@ pub use common::{
|
|||||||
// poll_unit::{EPollItems, WaitQueue},
|
// poll_unit::{EPollItems, WaitQueue},
|
||||||
EPollItems,
|
EPollItems,
|
||||||
};
|
};
|
||||||
pub use define::*;
|
pub use definition::*;
|
||||||
pub use endpoint::*;
|
pub use endpoint::*;
|
||||||
pub use family::{AddressFamily, Family};
|
pub use family::{AddressFamily, Family};
|
||||||
pub use inode::Inode;
|
pub use inode::Inode;
|
||||||
|
@ -532,7 +532,7 @@ impl Socket for NetlinkSock {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_option(&self, level: OptionsLevel, name: usize, val: &[u8]) -> Result<(), SystemError> {
|
fn set_option(&self, level: OptionLevel, name: usize, val: &[u8]) -> Result<(), SystemError> {
|
||||||
return netlink_setsockopt(self, level, name, val);
|
return netlink_setsockopt(self, level, name, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1274,11 +1274,11 @@ fn netlink_getsockbyportid(
|
|||||||
/// 设置 netlink 套接字的选项
|
/// 设置 netlink 套接字的选项
|
||||||
fn netlink_setsockopt(
|
fn netlink_setsockopt(
|
||||||
nlk: &NetlinkSock,
|
nlk: &NetlinkSock,
|
||||||
level: OptionsLevel,
|
level: OptionLevel,
|
||||||
optname: usize,
|
optname: usize,
|
||||||
optval: &[u8],
|
optval: &[u8],
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
if level != OptionsLevel::NETLINK {
|
if level != OptionLevel::NETLINK {
|
||||||
return Err(SystemError::ENOPROTOOPT);
|
return Err(SystemError::ENOPROTOOPT);
|
||||||
}
|
}
|
||||||
let optlen = optval.len();
|
let optlen = optval.len();
|
||||||
|
@ -243,7 +243,7 @@ impl Socket for SeqpacketSocket {
|
|||||||
|
|
||||||
fn set_option(
|
fn set_option(
|
||||||
&self,
|
&self,
|
||||||
_level: crate::net::socket::OptionsLevel,
|
_level: crate::net::socket::OptionLevel,
|
||||||
_optname: usize,
|
_optname: usize,
|
||||||
_optval: &[u8],
|
_optval: &[u8],
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
@ -293,7 +293,7 @@ impl Socket for SeqpacketSocket {
|
|||||||
|
|
||||||
fn get_option(
|
fn get_option(
|
||||||
&self,
|
&self,
|
||||||
_level: crate::net::socket::OptionsLevel,
|
_level: crate::net::socket::OptionLevel,
|
||||||
_name: usize,
|
_name: usize,
|
||||||
_value: &mut [u8],
|
_value: &mut [u8],
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
|
@ -243,7 +243,7 @@ impl Socket for StreamSocket {
|
|||||||
|
|
||||||
fn set_option(
|
fn set_option(
|
||||||
&self,
|
&self,
|
||||||
_level: OptionsLevel,
|
_level: OptionLevel,
|
||||||
_optname: usize,
|
_optname: usize,
|
||||||
_optval: &[u8],
|
_optval: &[u8],
|
||||||
) -> Result<(), SystemError> {
|
) -> Result<(), SystemError> {
|
||||||
@ -329,7 +329,7 @@ impl Socket for StreamSocket {
|
|||||||
|
|
||||||
fn get_option(
|
fn get_option(
|
||||||
&self,
|
&self,
|
||||||
_level: OptionsLevel,
|
_level: OptionLevel,
|
||||||
_name: usize,
|
_name: usize,
|
||||||
_value: &mut [u8],
|
_value: &mut [u8],
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
|
@ -142,7 +142,7 @@ impl Syscall {
|
|||||||
optname: usize,
|
optname: usize,
|
||||||
optval: &[u8],
|
optval: &[u8],
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
let sol = socket::OptionsLevel::try_from(level as u32)?;
|
let sol = socket::OptionLevel::try_from(level as u32)?;
|
||||||
let socket: Arc<socket::Inode> = ProcessManager::current_pcb()
|
let socket: Arc<socket::Inode> = ProcessManager::current_pcb()
|
||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(SystemError::EBADF)?;
|
.ok_or(SystemError::EBADF)?;
|
||||||
@ -172,10 +172,10 @@ impl Syscall {
|
|||||||
.get_socket(fd as i32)
|
.get_socket(fd as i32)
|
||||||
.ok_or(EBADF)?;
|
.ok_or(EBADF)?;
|
||||||
|
|
||||||
let level = socket::OptionsLevel::try_from(level as u32)?;
|
let level = socket::OptionLevel::try_from(level as u32)?;
|
||||||
|
|
||||||
use socket::Options as SO;
|
use socket::Options as SO;
|
||||||
use socket::OptionsLevel as SOL;
|
use socket::OptionLevel as SOL;
|
||||||
if matches!(level, SOL::SOCKET) {
|
if matches!(level, SOL::SOCKET) {
|
||||||
let optname = SO::try_from(optname as u32).map_err(|_| ENOPROTOOPT)?;
|
let optname = SO::try_from(optname as u32).map_err(|_| ENOPROTOOPT)?;
|
||||||
match optname {
|
match optname {
|
||||||
@ -209,10 +209,11 @@ impl Syscall {
|
|||||||
// protocol number of TCP.
|
// protocol number of TCP.
|
||||||
|
|
||||||
if matches!(level, SOL::TCP) {
|
if matches!(level, SOL::TCP) {
|
||||||
|
use socket::inet::stream::TcpOption;
|
||||||
let optname =
|
let optname =
|
||||||
PosixTcpSocketOptions::try_from(optname as i32).map_err(|_| ENOPROTOOPT)?;
|
TcpOption::try_from(optname as i32).map_err(|_| ENOPROTOOPT)?;
|
||||||
match optname {
|
match optname {
|
||||||
PosixTcpSocketOptions::Congestion => return Ok(0),
|
TcpOption::Congestion => return Ok(0),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ENOPROTOOPT);
|
return Err(ENOPROTOOPT);
|
||||||
}
|
}
|
||||||
@ -548,92 +549,3 @@ impl Syscall {
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user