mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-18 20:16:42 +00:00
Refactor current net codes
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
f6b327dbda
commit
ddb7be9296
@ -55,7 +55,7 @@ const COMMON_ARGS: &[&str] = &[
|
|||||||
"-device",
|
"-device",
|
||||||
"isa-debug-exit,iobase=0xf4,iosize=0x04",
|
"isa-debug-exit,iobase=0xf4,iosize=0x04",
|
||||||
"-netdev",
|
"-netdev",
|
||||||
"user,id=net01,hostfwd=tcp::30022-:22,hostfwd=tcp::30080-:8080",
|
"user,id=net01,hostfwd=tcp::30033-:22,hostfwd=tcp::30088-:8080",
|
||||||
"-object",
|
"-object",
|
||||||
"filter-dump,id=filter0,netdev=net01,file=virtio-net.pcap",
|
"filter-dump,id=filter0,netdev=net01,file=virtio-net.pcap",
|
||||||
];
|
];
|
||||||
|
@ -3,14 +3,15 @@ pub mod hpet;
|
|||||||
pub mod pit;
|
pub mod pit;
|
||||||
|
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use core::sync::atomic::{AtomicU64, Ordering};
|
use core::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
||||||
|
|
||||||
use alloc::{boxed::Box, collections::BinaryHeap, sync::Arc, vec::Vec};
|
use alloc::{boxed::Box, collections::BinaryHeap, sync::Arc, vec::Vec};
|
||||||
use spin::{Mutex, Once};
|
use spin::Once;
|
||||||
use trapframe::TrapFrame;
|
use trapframe::TrapFrame;
|
||||||
|
|
||||||
use crate::arch::x86::kernel;
|
use crate::arch::x86::kernel;
|
||||||
use crate::config::TIMER_FREQ;
|
use crate::config::TIMER_FREQ;
|
||||||
|
use crate::sync::SpinLock;
|
||||||
use crate::trap::IrqAllocateHandle;
|
use crate::trap::IrqAllocateHandle;
|
||||||
|
|
||||||
use self::apic::APIC_TIMER_CALLBACK;
|
use self::apic::APIC_TIMER_CALLBACK;
|
||||||
@ -21,7 +22,7 @@ pub static TICK: AtomicU64 = AtomicU64::new(0);
|
|||||||
static TIMER_IRQ: Once<IrqAllocateHandle> = Once::new();
|
static TIMER_IRQ: Once<IrqAllocateHandle> = Once::new();
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
TIMEOUT_LIST.call_once(|| Mutex::new(BinaryHeap::new()));
|
TIMEOUT_LIST.call_once(|| SpinLock::new(BinaryHeap::new()));
|
||||||
if kernel::apic::APIC_INSTANCE.is_completed() {
|
if kernel::apic::APIC_INSTANCE.is_completed() {
|
||||||
apic::init();
|
apic::init();
|
||||||
} else {
|
} else {
|
||||||
@ -53,13 +54,13 @@ fn timer_callback(trap_frame: &TrapFrame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TIMEOUT_LIST: Once<Mutex<BinaryHeap<Arc<TimerCallback>>>> = Once::new();
|
static TIMEOUT_LIST: Once<SpinLock<BinaryHeap<Arc<TimerCallback>>>> = Once::new();
|
||||||
|
|
||||||
pub struct TimerCallback {
|
pub struct TimerCallback {
|
||||||
expire_ms: u64,
|
expire_ms: u64,
|
||||||
data: Arc<dyn Any + Send + Sync>,
|
data: Arc<dyn Any + Send + Sync>,
|
||||||
callback: Box<dyn Fn(&TimerCallback) + Send + Sync>,
|
callback: Box<dyn Fn(&TimerCallback) + Send + Sync>,
|
||||||
enable: Mutex<bool>,
|
enable: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TimerCallback {
|
impl TimerCallback {
|
||||||
@ -72,7 +73,7 @@ impl TimerCallback {
|
|||||||
expire_ms: timeout_ms,
|
expire_ms: timeout_ms,
|
||||||
data,
|
data,
|
||||||
callback,
|
callback,
|
||||||
enable: Mutex::new(true),
|
enable: AtomicBool::new(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,16 +83,16 @@ impl TimerCallback {
|
|||||||
|
|
||||||
/// disable this timeout
|
/// disable this timeout
|
||||||
pub fn disable(&self) {
|
pub fn disable(&self) {
|
||||||
*self.enable.lock() = false;
|
self.enable.store(false, Ordering::Release)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// enable this timeout
|
/// enable this timeout
|
||||||
pub fn enable(&self) {
|
pub fn enable(&self) {
|
||||||
*self.enable.lock() = true;
|
self.enable.store(false, Ordering::Release)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_enable(&self) -> bool {
|
pub fn is_enable(&self) -> bool {
|
||||||
*self.enable.lock()
|
self.enable.load(Ordering::Acquire)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +126,7 @@ where
|
|||||||
T: Any + Send + Sync,
|
T: Any + Send + Sync,
|
||||||
{
|
{
|
||||||
let timer_callback = TimerCallback::new(
|
let timer_callback = TimerCallback::new(
|
||||||
TICK.load(Ordering::SeqCst) + timeout,
|
TICK.load(Ordering::Acquire) + timeout,
|
||||||
Arc::new(data),
|
Arc::new(data),
|
||||||
Box::new(callback),
|
Box::new(callback),
|
||||||
);
|
);
|
||||||
@ -137,5 +138,5 @@ where
|
|||||||
/// The time since the system boots up.
|
/// The time since the system boots up.
|
||||||
/// The currently returned results are in milliseconds.
|
/// The currently returned results are in milliseconds.
|
||||||
pub fn read_monotonic_milli_seconds() -> u64 {
|
pub fn read_monotonic_milli_seconds() -> u64 {
|
||||||
TICK.load(Ordering::SeqCst) * (1000 / TIMER_FREQ)
|
TICK.load(Ordering::Acquire) * (1000 / TIMER_FREQ)
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
NETTEST_DIR=/regression/network
|
NETTEST_DIR=/regression/network
|
||||||
cd ${NETTEST_DIR}
|
cd ${NETTEST_DIR}
|
||||||
echo "Start net test......"
|
echo "Start net test......"
|
||||||
./tcp_server &
|
# ./tcp_server &
|
||||||
./tcp_client
|
# ./tcp_client
|
||||||
./udp_server &
|
# ./udp_server &
|
||||||
./udp_client
|
# ./udp_client
|
||||||
|
./unix_server &
|
||||||
|
./unix_client
|
||||||
|
./socketpair
|
||||||
|
|
||||||
echo "All net test passed"
|
echo "All net test passed"
|
||||||
|
@ -370,7 +370,7 @@ impl<'a> TryFrom<&'a str> for FsPath<'a> {
|
|||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// The path "/dir/file/" will be split to ("/dir", "file/").
|
/// The path "/dir/file/" will be split to ("/dir", "file/").
|
||||||
fn split_path(path: &str) -> (&str, &str) {
|
pub fn split_path(path: &str) -> (&str, &str) {
|
||||||
let file_name = path
|
let file_name = path
|
||||||
.split_inclusive('/')
|
.split_inclusive('/')
|
||||||
.filter(|&x| x != "/")
|
.filter(|&x| x != "/")
|
||||||
|
@ -18,27 +18,7 @@ impl PipeReader {
|
|||||||
|
|
||||||
impl FileLike for PipeReader {
|
impl FileLike for PipeReader {
|
||||||
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||||
let is_nonblocking = self.consumer.is_nonblocking();
|
self.consumer.read(buf)
|
||||||
|
|
||||||
// Fast path
|
|
||||||
let res = self.consumer.read(buf);
|
|
||||||
if should_io_return(&res, is_nonblocking) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slow path
|
|
||||||
let mask = IoEvents::IN;
|
|
||||||
let poller = Poller::new();
|
|
||||||
loop {
|
|
||||||
let res = self.consumer.read(buf);
|
|
||||||
if should_io_return(&res, is_nonblocking) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
let events = self.poll(mask, Some(&poller));
|
|
||||||
if events.is_empty() {
|
|
||||||
poller.wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||||
@ -104,27 +84,7 @@ impl PipeWriter {
|
|||||||
|
|
||||||
impl FileLike for PipeWriter {
|
impl FileLike for PipeWriter {
|
||||||
fn write(&self, buf: &[u8]) -> Result<usize> {
|
fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||||
let is_nonblocking = self.producer.is_nonblocking();
|
self.producer.write(buf)
|
||||||
|
|
||||||
// Fast path
|
|
||||||
let res = self.producer.write(buf);
|
|
||||||
if should_io_return(&res, is_nonblocking) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slow path
|
|
||||||
let mask = IoEvents::OUT;
|
|
||||||
let poller = Poller::new();
|
|
||||||
loop {
|
|
||||||
let res = self.producer.write(buf);
|
|
||||||
if should_io_return(&res, is_nonblocking) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
let events = self.poll(mask, Some(&poller));
|
|
||||||
if events.is_empty() {
|
|
||||||
poller.wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents {
|
||||||
|
@ -117,6 +117,15 @@ impl Inode_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_socket(ino: usize, mode: InodeMode, sb: &SuperBlock) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Inner::Socket,
|
||||||
|
metadata: Metadata::new_socket(ino, mode, sb),
|
||||||
|
this: Weak::default(),
|
||||||
|
fs: Weak::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_device(
|
pub fn new_device(
|
||||||
ino: usize,
|
ino: usize,
|
||||||
mode: InodeMode,
|
mode: InodeMode,
|
||||||
@ -153,6 +162,7 @@ enum Inner {
|
|||||||
File,
|
File,
|
||||||
SymLink(Str256),
|
SymLink(Str256),
|
||||||
Device(Arc<dyn Device>),
|
Device(Arc<dyn Device>),
|
||||||
|
Socket,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Inner {
|
impl Inner {
|
||||||
@ -489,6 +499,24 @@ impl Inode for RamInode {
|
|||||||
self_inode.metadata.nlinks += 1;
|
self_inode.metadata.nlinks += 1;
|
||||||
dir_inode
|
dir_inode
|
||||||
}
|
}
|
||||||
|
InodeType::SymLink => {
|
||||||
|
let sym_inode = Arc::new(RamInode(RwLock::new(Inode_::new_symlink(
|
||||||
|
fs.alloc_id(),
|
||||||
|
mode,
|
||||||
|
&fs.sb(),
|
||||||
|
))));
|
||||||
|
sym_inode.0.write().fs = self_inode.fs.clone();
|
||||||
|
sym_inode
|
||||||
|
}
|
||||||
|
InodeType::Socket => {
|
||||||
|
let socket_inode = Arc::new(RamInode(RwLock::new(Inode_::new_socket(
|
||||||
|
fs.alloc_id(),
|
||||||
|
mode,
|
||||||
|
&fs.sb(),
|
||||||
|
))));
|
||||||
|
socket_inode.0.write().fs = self_inode.fs.clone();
|
||||||
|
socket_inode
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("unsupported inode type");
|
panic!("unsupported inode type");
|
||||||
}
|
}
|
||||||
|
@ -134,6 +134,30 @@ impl<T> Producer<T> {
|
|||||||
|
|
||||||
impl<T: Copy> Producer<T> {
|
impl<T: Copy> Producer<T> {
|
||||||
pub fn write(&self, buf: &[T]) -> Result<usize> {
|
pub fn write(&self, buf: &[T]) -> Result<usize> {
|
||||||
|
let is_nonblocking = self.is_nonblocking();
|
||||||
|
|
||||||
|
// Fast path
|
||||||
|
let res = self.try_write(buf);
|
||||||
|
if should_io_return(&res, is_nonblocking) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slow path
|
||||||
|
let mask = IoEvents::OUT;
|
||||||
|
let poller = Poller::new();
|
||||||
|
loop {
|
||||||
|
let res = self.try_write(buf);
|
||||||
|
if should_io_return(&res, is_nonblocking) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
let events = self.poll(mask, Some(&poller));
|
||||||
|
if events.is_empty() {
|
||||||
|
poller.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_write(&self, buf: &[T]) -> Result<usize> {
|
||||||
if self.is_shutdown() || self.is_peer_shutdown() {
|
if self.is_shutdown() || self.is_peer_shutdown() {
|
||||||
return_errno!(Errno::EPIPE);
|
return_errno!(Errno::EPIPE);
|
||||||
}
|
}
|
||||||
@ -198,10 +222,33 @@ impl<T> Consumer<T> {
|
|||||||
|
|
||||||
impl<T: Copy> Consumer<T> {
|
impl<T: Copy> Consumer<T> {
|
||||||
pub fn read(&self, buf: &mut [T]) -> Result<usize> {
|
pub fn read(&self, buf: &mut [T]) -> Result<usize> {
|
||||||
|
let is_nonblocking = self.is_nonblocking();
|
||||||
|
|
||||||
|
// Fast path
|
||||||
|
let res = self.try_read(buf);
|
||||||
|
if should_io_return(&res, is_nonblocking) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slow path
|
||||||
|
let mask = IoEvents::IN;
|
||||||
|
let poller = Poller::new();
|
||||||
|
loop {
|
||||||
|
let res = self.try_read(buf);
|
||||||
|
if should_io_return(&res, is_nonblocking) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
let events = self.poll(mask, Some(&poller));
|
||||||
|
if events.is_empty() {
|
||||||
|
poller.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_read(&self, buf: &mut [T]) -> Result<usize> {
|
||||||
if self.is_shutdown() {
|
if self.is_shutdown() {
|
||||||
return_errno!(Errno::EPIPE);
|
return_errno!(Errno::EPIPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if buf.len() == 0 {
|
if buf.len() == 0 {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@ -347,3 +394,14 @@ fn check_status_flags(flags: StatusFlags) -> Result<()> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn should_io_return(res: &Result<usize>, is_nonblocking: bool) -> bool {
|
||||||
|
if is_nonblocking {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
match res {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(e) if e.error() == Errno::EAGAIN => false,
|
||||||
|
Err(_) => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,7 +5,7 @@ use alloc::string::String;
|
|||||||
use core::sync::atomic::{AtomicU32, Ordering};
|
use core::sync::atomic::{AtomicU32, Ordering};
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
use super::{FileSystem, InodeMode, InodeType, Metadata, MountNode, Vnode, NAME_MAX};
|
use super::{FileSystem, Inode, InodeMode, InodeType, Metadata, Vnode, NAME_MAX};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref DCACHE: Mutex<BTreeMap<DentryKey, Arc<Dentry>>> = Mutex::new(BTreeMap::new());
|
static ref DCACHE: Mutex<BTreeMap<DentryKey, Arc<Dentry>>> = Mutex::new(BTreeMap::new());
|
||||||
@ -162,6 +162,8 @@ impl Dentry {
|
|||||||
/// Get the mount node which the dentry belongs to.
|
/// Get the mount node which the dentry belongs to.
|
||||||
pub fn mount_node(&self) -> Arc<MountNode> {
|
pub fn mount_node(&self) -> Arc<MountNode> {
|
||||||
self.mount_node.upgrade().unwrap()
|
self.mount_node.upgrade().unwrap()
|
||||||
|
pub fn inode(&self) -> Weak<dyn Inode> {
|
||||||
|
self.vnode.inode()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a dentry by making inode.
|
/// Create a dentry by making inode.
|
||||||
|
@ -204,6 +204,25 @@ impl Metadata {
|
|||||||
rdev: device.id().into(),
|
rdev: device.id().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_socket(ino: usize, mode: InodeMode, sb: &SuperBlock) -> Metadata {
|
||||||
|
Self {
|
||||||
|
dev: 0,
|
||||||
|
ino,
|
||||||
|
size: 0,
|
||||||
|
blk_size: sb.bsize,
|
||||||
|
blocks: 0,
|
||||||
|
atime: Default::default(),
|
||||||
|
mtime: Default::default(),
|
||||||
|
ctime: Default::default(),
|
||||||
|
type_: InodeType::Socket,
|
||||||
|
mode,
|
||||||
|
nlinks: 1,
|
||||||
|
uid: 0,
|
||||||
|
gid: 0,
|
||||||
|
rdev: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Inode: Any + Sync + Send {
|
pub trait Inode: Any + Sync + Send {
|
||||||
|
@ -211,6 +211,11 @@ impl Vnode {
|
|||||||
self.inner.read().inode.metadata()
|
self.inner.read().inode.metadata()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn inode(&self) -> Weak<dyn Inode> {
|
||||||
|
let inner = self.inner.read();
|
||||||
|
Arc::downgrade(&inner.inode)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn inode_type(&self) -> InodeType {
|
pub fn inode_type(&self) -> InodeType {
|
||||||
self.inner.read().inode.metadata().type_
|
self.inner.read().inode.metadata().type_
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ pub use self::util::sock_options::{SockOptionLevel, SockOptionName};
|
|||||||
pub use self::util::sockaddr::SocketAddr;
|
pub use self::util::sockaddr::SocketAddr;
|
||||||
|
|
||||||
pub mod ip;
|
pub mod ip;
|
||||||
|
pub mod unix;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
/// Operations defined on a socket.
|
/// Operations defined on a socket.
|
||||||
|
@ -13,3 +13,13 @@ pub enum SockShutdownCmd {
|
|||||||
/// Shutdown receptions and transmissions
|
/// Shutdown receptions and transmissions
|
||||||
SHUT_RDWR = 2,
|
SHUT_RDWR = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SockShutdownCmd {
|
||||||
|
pub fn shut_read(&self) -> bool {
|
||||||
|
*self == Self::SHUT_RD || *self == Self::SHUT_RDWR
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shut_write(&self) -> bool {
|
||||||
|
*self == Self::SHUT_WR || *self == Self::SHUT_RDWR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@ type PortNum = u16;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SocketAddr {
|
pub enum SocketAddr {
|
||||||
Unix,
|
Unix(String),
|
||||||
IPv4(Ipv4Address, PortNum),
|
IPv4(Ipv4Address, PortNum),
|
||||||
IPv6,
|
IPv6,
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::util::write_socket_addr_to_user;
|
use crate::util::net::write_socket_addr_to_user;
|
||||||
|
use crate::util::read_val_from_user;
|
||||||
use crate::{fs::file_table::FileDescripter, prelude::*};
|
use crate::{fs::file_table::FileDescripter, prelude::*};
|
||||||
use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry};
|
use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry};
|
||||||
|
|
||||||
@ -8,9 +9,10 @@ use super::SYS_ACCEPT;
|
|||||||
pub fn sys_accept(
|
pub fn sys_accept(
|
||||||
sockfd: FileDescripter,
|
sockfd: FileDescripter,
|
||||||
sockaddr_ptr: Vaddr,
|
sockaddr_ptr: Vaddr,
|
||||||
addr_len: u32,
|
addr_len_ptr: Vaddr,
|
||||||
) -> Result<SyscallReturn> {
|
) -> Result<SyscallReturn> {
|
||||||
log_syscall_entry!(SYS_ACCEPT);
|
log_syscall_entry!(SYS_ACCEPT);
|
||||||
|
let addr_len: i32 = read_val_from_user(addr_len_ptr)?;
|
||||||
debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addr_len = {addr_len}");
|
debug!("sockfd = {sockfd}, sockaddr_ptr = 0x{sockaddr_ptr:x}, addr_len = {addr_len}");
|
||||||
let current = current!();
|
let current = current!();
|
||||||
get_socket_without_holding_filetable_lock!(socket, current, sockfd);
|
get_socket_without_holding_filetable_lock!(socket, current, sockfd);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::log_syscall_entry;
|
use crate::log_syscall_entry;
|
||||||
use crate::util::read_socket_addr_from_user;
|
use crate::util::net::read_socket_addr_from_user;
|
||||||
use crate::{fs::file_table::FileDescripter, prelude::*};
|
use crate::{fs::file_table::FileDescripter, prelude::*};
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
|
@ -2,7 +2,7 @@ use crate::fs::file_table::FileDescripter;
|
|||||||
use crate::get_socket_without_holding_filetable_lock;
|
use crate::get_socket_without_holding_filetable_lock;
|
||||||
use crate::log_syscall_entry;
|
use crate::log_syscall_entry;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::util::read_socket_addr_from_user;
|
use crate::util::net::read_socket_addr_from_user;
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use super::SYS_CONNECT;
|
use super::SYS_CONNECT;
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
use crate::util::write_socket_addr_to_user;
|
use crate::util::net::write_socket_addr_to_user;
|
||||||
|
use crate::util::read_val_from_user;
|
||||||
use crate::{fs::file_table::FileDescripter, log_syscall_entry, prelude::*};
|
use crate::{fs::file_table::FileDescripter, log_syscall_entry, prelude::*};
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use super::SYS_GETPEERNAME;
|
use super::SYS_GETPEERNAME;
|
||||||
|
|
||||||
pub fn sys_getpeername(sockfd: FileDescripter, addr: Vaddr, addrlen: u32) -> Result<SyscallReturn> {
|
pub fn sys_getpeername(
|
||||||
|
sockfd: FileDescripter,
|
||||||
|
addr: Vaddr,
|
||||||
|
addrlen_ptr: Vaddr,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
log_syscall_entry!(SYS_GETPEERNAME);
|
log_syscall_entry!(SYS_GETPEERNAME);
|
||||||
|
let addrlen: i32 = read_val_from_user(addrlen_ptr)?;
|
||||||
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}");
|
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}");
|
||||||
let socket_addr = {
|
let socket_addr = {
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
use crate::fs::file_table::FileDescripter;
|
use crate::fs::file_table::FileDescripter;
|
||||||
use crate::log_syscall_entry;
|
use crate::log_syscall_entry;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::util::write_socket_addr_to_user;
|
use crate::util::net::write_socket_addr_to_user;
|
||||||
|
use crate::util::read_val_from_user;
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use super::SYS_GETSOCKNAME;
|
use super::SYS_GETSOCKNAME;
|
||||||
|
|
||||||
pub fn sys_getsockname(sockfd: FileDescripter, addr: Vaddr, addrlen: u32) -> Result<SyscallReturn> {
|
pub fn sys_getsockname(
|
||||||
|
sockfd: FileDescripter,
|
||||||
|
addr: Vaddr,
|
||||||
|
addrlen_ptr: Vaddr,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
log_syscall_entry!(SYS_GETSOCKNAME);
|
log_syscall_entry!(SYS_GETSOCKNAME);
|
||||||
|
let addrlen: i32 = read_val_from_user(addrlen_ptr)?;
|
||||||
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}");
|
debug!("sockfd = {sockfd}, addr = 0x{addr:x}, addrlen = {addrlen}");
|
||||||
let socket_addr = {
|
let socket_addr = {
|
||||||
let current = current!();
|
let current = current!();
|
||||||
|
@ -86,6 +86,7 @@ use self::sendto::sys_sendto;
|
|||||||
use self::setsockopt::sys_setsockopt;
|
use self::setsockopt::sys_setsockopt;
|
||||||
use self::shutdown::sys_shutdown;
|
use self::shutdown::sys_shutdown;
|
||||||
use self::socket::sys_socket;
|
use self::socket::sys_socket;
|
||||||
|
use self::socketpair::sys_socketpair;
|
||||||
|
|
||||||
mod accept;
|
mod accept;
|
||||||
mod access;
|
mod access;
|
||||||
@ -157,6 +158,7 @@ mod setpgid;
|
|||||||
mod setsockopt;
|
mod setsockopt;
|
||||||
mod shutdown;
|
mod shutdown;
|
||||||
mod socket;
|
mod socket;
|
||||||
|
mod socketpair;
|
||||||
mod stat;
|
mod stat;
|
||||||
mod statfs;
|
mod statfs;
|
||||||
mod symlink;
|
mod symlink;
|
||||||
@ -240,6 +242,7 @@ define_syscall_nums!(
|
|||||||
SYS_LISTEN = 50,
|
SYS_LISTEN = 50,
|
||||||
SYS_GETSOCKNAME = 51,
|
SYS_GETSOCKNAME = 51,
|
||||||
SYS_GETPEERNAME = 52,
|
SYS_GETPEERNAME = 52,
|
||||||
|
SYS_SOCKETPAIR = 53,
|
||||||
SYS_SETSOCKOPT = 54,
|
SYS_SETSOCKOPT = 54,
|
||||||
SYS_GETSOCKOPT = 55,
|
SYS_GETSOCKOPT = 55,
|
||||||
SYS_CLONE = 56,
|
SYS_CLONE = 56,
|
||||||
@ -400,6 +403,7 @@ pub fn syscall_dispatch(
|
|||||||
SYS_LISTEN => syscall_handler!(2, sys_listen, args),
|
SYS_LISTEN => syscall_handler!(2, sys_listen, args),
|
||||||
SYS_GETSOCKNAME => syscall_handler!(3, sys_getsockname, args),
|
SYS_GETSOCKNAME => syscall_handler!(3, sys_getsockname, args),
|
||||||
SYS_GETPEERNAME => syscall_handler!(3, sys_getpeername, args),
|
SYS_GETPEERNAME => syscall_handler!(3, sys_getpeername, args),
|
||||||
|
SYS_SOCKETPAIR => syscall_handler!(4, sys_socketpair, args),
|
||||||
SYS_SETSOCKOPT => syscall_handler!(5, sys_setsockopt, args),
|
SYS_SETSOCKOPT => syscall_handler!(5, sys_setsockopt, args),
|
||||||
SYS_GETSOCKOPT => syscall_handler!(5, sys_getsockopt, args),
|
SYS_GETSOCKOPT => syscall_handler!(5, sys_getsockopt, args),
|
||||||
SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()),
|
SYS_CLONE => syscall_handler!(5, sys_clone, args, context.clone()),
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::net::socket::SendRecvFlags;
|
use crate::net::socket::SendRecvFlags;
|
||||||
use crate::util::{
|
use crate::util::net::write_socket_addr_to_user;
|
||||||
read_val_from_user, write_bytes_to_user, write_socket_addr_to_user, write_val_to_user,
|
use crate::util::{read_val_from_user, write_bytes_to_user, write_val_to_user};
|
||||||
};
|
|
||||||
use crate::{fs::file_table::FileDescripter, prelude::*};
|
use crate::{fs::file_table::FileDescripter, prelude::*};
|
||||||
use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry};
|
use crate::{get_socket_without_holding_filetable_lock, log_syscall_entry};
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ use crate::get_socket_without_holding_filetable_lock;
|
|||||||
use crate::log_syscall_entry;
|
use crate::log_syscall_entry;
|
||||||
use crate::net::socket::SendRecvFlags;
|
use crate::net::socket::SendRecvFlags;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use crate::util::net::read_socket_addr_from_user;
|
||||||
use crate::util::read_bytes_from_user;
|
use crate::util::read_bytes_from_user;
|
||||||
use crate::util::read_socket_addr_from_user;
|
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
use super::SYS_SENDTO;
|
use super::SYS_SENDTO;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::fs::file_handle::FileLike;
|
use crate::fs::file_handle::FileLike;
|
||||||
use crate::net::socket::ip::DatagramSocket;
|
use crate::net::socket::ip::{DatagramSocket, StreamSocket};
|
||||||
use crate::net::socket::ip::StreamSocket;
|
use crate::net::socket::unix::UnixStreamSocket;
|
||||||
use crate::util::net::SaFamily;
|
use crate::util::net::{Protocol, SaFamily, SockFlags, SockType, SOCK_TYPE_MASK};
|
||||||
use crate::{log_syscall_entry, prelude::*};
|
use crate::{log_syscall_entry, prelude::*};
|
||||||
|
|
||||||
use super::SyscallReturn;
|
use super::SyscallReturn;
|
||||||
@ -19,6 +19,9 @@ pub fn sys_socket(domain: i32, type_: i32, protocol: i32) -> Result<SyscallRetur
|
|||||||
);
|
);
|
||||||
let nonblocking = sock_flags.contains(SockFlags::SOCK_NONBLOCK);
|
let nonblocking = sock_flags.contains(SockFlags::SOCK_NONBLOCK);
|
||||||
let file_like = match (domain, sock_type, protocol) {
|
let file_like = match (domain, sock_type, protocol) {
|
||||||
|
(SaFamily::AF_UNIX, SockType::SOCK_STREAM, _) => Arc::new(UnixStreamSocket::new(
|
||||||
|
sock_flags.contains(SockFlags::SOCK_NONBLOCK),
|
||||||
|
)) as Arc<dyn FileLike>,
|
||||||
(
|
(
|
||||||
SaFamily::AF_INET,
|
SaFamily::AF_INET,
|
||||||
SockType::SOCK_STREAM,
|
SockType::SOCK_STREAM,
|
||||||
@ -36,70 +39,3 @@ pub fn sys_socket(domain: i32, type_: i32, protocol: i32) -> Result<SyscallRetur
|
|||||||
};
|
};
|
||||||
Ok(SyscallReturn::Return(fd as _))
|
Ok(SyscallReturn::Return(fd as _))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(i32)]
|
|
||||||
#[derive(Debug, Clone, Copy, TryFromInt)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
/// Standard well-defined IP protocols.
|
|
||||||
/// From https://elixir.bootlin.com/linux/v6.0.9/source/include/uapi/linux/in.h.
|
|
||||||
enum Protocol {
|
|
||||||
IPPROTO_IP = 0, /* Dummy protocol for TCP */
|
|
||||||
IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
|
|
||||||
IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
|
|
||||||
IPPROTO_TCP = 6, /* Transmission Control Protocol */
|
|
||||||
IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
|
|
||||||
IPPROTO_PUP = 12, /* PUP protocol */
|
|
||||||
IPPROTO_UDP = 17, /* User Datagram Protocol */
|
|
||||||
IPPROTO_IDP = 22, /* XNS IDP protocol */
|
|
||||||
IPPROTO_TP = 29, /* SO Transport Protocol Class 4 */
|
|
||||||
IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
|
|
||||||
IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
|
|
||||||
IPPROTO_RSVP = 46, /* RSVP Protocol */
|
|
||||||
IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
|
|
||||||
IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
|
|
||||||
IPPROTO_AH = 51, /* Authentication Header protocol */
|
|
||||||
IPPROTO_MTP = 92, /* Multicast Transport Protocol */
|
|
||||||
IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
|
|
||||||
IPPROTO_ENCAP = 98, /* Encapsulation Header */
|
|
||||||
IPPROTO_PIM = 103, /* Protocol Independent Multicast */
|
|
||||||
IPPROTO_COMP = 108, /* Compression Header Protocol */
|
|
||||||
IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
|
|
||||||
IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
|
|
||||||
IPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */
|
|
||||||
IPPROTO_ETHERNET = 143, /* Ethernet-within-IPv6 Encapsulation */
|
|
||||||
IPPROTO_RAW = 255, /* Raw IP packets */
|
|
||||||
IPPROTO_MPTCP = 262, /* Multipath TCP connection */
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(i32)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[derive(Debug, Clone, Copy, TryFromInt)]
|
|
||||||
/// Socket types.
|
|
||||||
/// From https://elixir.bootlin.com/linux/v6.0.9/source/include/linux/net.h
|
|
||||||
enum SockType {
|
|
||||||
/// Stream socket
|
|
||||||
SOCK_STREAM = 1,
|
|
||||||
/// Datagram socket
|
|
||||||
SOCK_DGRAM = 2,
|
|
||||||
/// Raw socket
|
|
||||||
SOCK_RAW = 3,
|
|
||||||
/// Reliably-delivered message
|
|
||||||
SOCK_RDM = 4,
|
|
||||||
/// Sequential packet socket
|
|
||||||
SOCK_SEQPACKET = 5,
|
|
||||||
/// Datagram Congestion Control Protocol socket
|
|
||||||
SOCK_DCCP = 6,
|
|
||||||
/// Linux specific way of getting packets at the dev level
|
|
||||||
SOCK_PACKET = 10,
|
|
||||||
}
|
|
||||||
|
|
||||||
const SOCK_TYPE_MASK: i32 = 0xf;
|
|
||||||
|
|
||||||
bitflags! {
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Pod)]
|
|
||||||
struct SockFlags: i32 {
|
|
||||||
const SOCK_NONBLOCK = 1 << 11;
|
|
||||||
const SOCK_CLOEXEC = 1 << 19;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
use crate::{
|
use crate::prelude::*;
|
||||||
net::socket::SocketAddr,
|
|
||||||
prelude::*,
|
|
||||||
util::net::{InAddr, SaFamily, SockAddr, SockAddrIn, SockAddrIn6, SockAddrUn},
|
|
||||||
};
|
|
||||||
use jinux_frame::vm::VmIo;
|
use jinux_frame::vm::VmIo;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
|
|
||||||
@ -40,51 +36,3 @@ pub fn read_cstring_from_user(addr: Vaddr, max_len: usize) -> Result<CString> {
|
|||||||
read_bytes_from_user(addr, &mut buffer)?;
|
read_bytes_from_user(addr, &mut buffer)?;
|
||||||
Ok(CString::from(CStr::from_bytes_until_nul(&buffer)?))
|
Ok(CString::from(CStr::from_bytes_until_nul(&buffer)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_socket_addr_from_user(addr: Vaddr, addr_len: usize) -> Result<SocketAddr> {
|
|
||||||
debug_assert!(addr_len >= core::mem::size_of::<SockAddr>());
|
|
||||||
let sockaddr: SockAddr = read_val_from_user(addr)?;
|
|
||||||
let socket_addr = match sockaddr.sa_family()? {
|
|
||||||
SaFamily::AF_UNSPEC => {
|
|
||||||
return_errno_with_message!(Errno::EINVAL, "the socket addr family is unspecified")
|
|
||||||
}
|
|
||||||
SaFamily::AF_UNIX => {
|
|
||||||
debug_assert!(addr_len >= core::mem::size_of::<SockAddrUn>());
|
|
||||||
let sock_addr_un: SockAddrUn = read_val_from_user(addr)?;
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
SaFamily::AF_INET => {
|
|
||||||
debug_assert!(addr_len >= core::mem::size_of::<SockAddrIn>());
|
|
||||||
let sock_addr_in: SockAddrIn = read_val_from_user(addr)?;
|
|
||||||
SocketAddr::from(sock_addr_in)
|
|
||||||
}
|
|
||||||
SaFamily::AF_INET6 => {
|
|
||||||
debug_assert!(addr_len >= core::mem::size_of::<SockAddrIn6>());
|
|
||||||
let sock_addr_in6: SockAddrIn6 = read_val_from_user(addr)?;
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return_errno_with_message!(Errno::EAFNOSUPPORT, "cannot support address for the family")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(socket_addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_socket_addr_to_user(
|
|
||||||
socket_addr: &SocketAddr,
|
|
||||||
dest: Vaddr,
|
|
||||||
max_len: usize,
|
|
||||||
) -> Result<usize> {
|
|
||||||
match socket_addr {
|
|
||||||
SocketAddr::Unix => todo!(),
|
|
||||||
SocketAddr::IPv4(addr, port) => {
|
|
||||||
let in_addr = InAddr::from(*addr);
|
|
||||||
let sock_addr_in = SockAddrIn::new(*port, in_addr);
|
|
||||||
let write_size = core::mem::size_of::<SockAddrIn>();
|
|
||||||
debug_assert!(max_len >= write_size);
|
|
||||||
write_val_to_user(dest, &sock_addr_in)?;
|
|
||||||
Ok(write_size)
|
|
||||||
}
|
|
||||||
SocketAddr::IPv6 => todo!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,213 +0,0 @@
|
|||||||
use crate::net::iface::Ipv4Address;
|
|
||||||
use crate::net::socket::SocketAddr;
|
|
||||||
use crate::prelude::*;
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! get_socket_without_holding_filetable_lock {
|
|
||||||
($name:tt, $current: expr, $sockfd: expr) => {
|
|
||||||
let file_like = {
|
|
||||||
let file_table = $current.file_table().lock();
|
|
||||||
file_table.get_file($sockfd)?.clone()
|
|
||||||
// Drop filetable here to avoid locking
|
|
||||||
};
|
|
||||||
let $name = file_like
|
|
||||||
.as_socket()
|
|
||||||
.ok_or_else(|| Error::with_message(Errno::ENOTSOCK, "the file is not socket"))?;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
|
||||||
#[repr(C)]
|
|
||||||
/// PlaceHolder
|
|
||||||
pub struct SockAddr {
|
|
||||||
sa_family: u16, // SaFamily
|
|
||||||
sa_data: [u8; 14],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SockAddr {
|
|
||||||
pub fn sa_family(&self) -> Result<SaFamily> {
|
|
||||||
Ok(SaFamily::try_from(self.sa_family as i32)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
|
||||||
pub struct SockAddrUn {
|
|
||||||
sun_family: u16, // Always SaFamily::AF_UNIX
|
|
||||||
sun_path: [u8; 108],
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
|
||||||
/// IPv4 4-byte address
|
|
||||||
pub struct InAddr {
|
|
||||||
s_addr: [u8; 4],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InAddr {
|
|
||||||
pub fn as_bytes(&self) -> &[u8] {
|
|
||||||
&self.s_addr
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Self {
|
|
||||||
debug_assert!(bytes.len() == 4);
|
|
||||||
let mut s_addr = [0u8; 4];
|
|
||||||
s_addr.copy_from_slice(bytes);
|
|
||||||
Self { s_addr }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct PortNum {
|
|
||||||
port: [u8; 2],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PortNum {
|
|
||||||
pub fn as_u16(&self) -> u16 {
|
|
||||||
u16::from_be_bytes(self.port)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_u16(value: u16) -> Self {
|
|
||||||
let bytes = value.to_be_bytes();
|
|
||||||
Self { port: bytes }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
|
||||||
/// IPv4 socket address
|
|
||||||
pub struct SockAddrIn {
|
|
||||||
/// always SaFamily::AF_INET
|
|
||||||
sin_family: u16,
|
|
||||||
/// Port number
|
|
||||||
sin_port_t: PortNum,
|
|
||||||
/// IPv4 address
|
|
||||||
sin_addr: InAddr,
|
|
||||||
/// Pad to size of 'SockAddr' structure (16 bytes)
|
|
||||||
_pad: [u8; 8],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SockAddrIn {
|
|
||||||
pub fn new(port: u16, addr: InAddr) -> Self {
|
|
||||||
let port = PortNum::from_u16(port);
|
|
||||||
Self {
|
|
||||||
sin_family: SaFamily::AF_INET as _,
|
|
||||||
sin_port_t: port,
|
|
||||||
sin_addr: addr,
|
|
||||||
_pad: [0u8; 8],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
|
||||||
/// IPv6 address
|
|
||||||
pub struct In6Addr {
|
|
||||||
s6_addr: [u8; 16],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl In6Addr {
|
|
||||||
pub fn as_bytes(&self) -> &[u8] {
|
|
||||||
&self.s6_addr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// IPv6 socket address
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy, Pod)]
|
|
||||||
pub struct SockAddrIn6 {
|
|
||||||
/// always SaFamily::AF_INET6
|
|
||||||
sin6_family: u16,
|
|
||||||
/// Port number
|
|
||||||
sin6_port: PortNum,
|
|
||||||
/// IPv6 flow information
|
|
||||||
sin6_flowinfo: u32,
|
|
||||||
/// IPv6 address
|
|
||||||
sin6_addr: In6Addr,
|
|
||||||
// Scope ID
|
|
||||||
sin6_scope_id: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Address family. The definition is from https://elixir.bootlin.com/linux/v6.0.9/source/include/linux/socket.h.
|
|
||||||
#[repr(i32)]
|
|
||||||
#[derive(Debug, Clone, Copy, TryFromInt)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub enum SaFamily {
|
|
||||||
AF_UNSPEC = 0,
|
|
||||||
AF_UNIX = 1, /* Unix domain sockets */
|
|
||||||
//AF_LOCAL 1 /* POSIX name for AF_UNIX */
|
|
||||||
AF_INET = 2, /* Internet IP Protocol */
|
|
||||||
AF_AX25 = 3, /* Amateur Radio AX.25 */
|
|
||||||
AF_IPX = 4, /* Novell IPX */
|
|
||||||
AF_APPLETALK = 5, /* AppleTalk DDP */
|
|
||||||
AF_NETROM = 6, /* Amateur Radio NET/ROM */
|
|
||||||
AF_BRIDGE = 7, /* Multiprotocol bridge */
|
|
||||||
AF_ATMPVC = 8, /* ATM PVCs */
|
|
||||||
AF_X25 = 9, /* Reserved for X.25 project */
|
|
||||||
AF_INET6 = 10, /* IP version 6 */
|
|
||||||
AF_ROSE = 11, /* Amateur Radio X.25 PLP */
|
|
||||||
AF_DECnet = 12, /* Reserved for DECnet project */
|
|
||||||
AF_NETBEUI = 13, /* Reserved for 802.2LLC project*/
|
|
||||||
AF_SECURITY = 14, /* Security callback pseudo AF */
|
|
||||||
AF_KEY = 15, /* PF_KEY key management API */
|
|
||||||
AF_NETLINK = 16,
|
|
||||||
//AF_ROUTE = AF_NETLINK /* Alias to emulate 4.4BSD */
|
|
||||||
AF_PACKET = 17, /* Packet family */
|
|
||||||
AF_ASH = 18, /* Ash */
|
|
||||||
AF_ECONET = 19, /* Acorn Econet */
|
|
||||||
AF_ATMSVC = 20, /* ATM SVCs */
|
|
||||||
AF_RDS = 21, /* RDS sockets */
|
|
||||||
AF_SNA = 22, /* Linux SNA Project (nutters!) */
|
|
||||||
AF_IRDA = 23, /* IRDA sockets */
|
|
||||||
AF_PPPOX = 24, /* PPPoX sockets */
|
|
||||||
AF_WANPIPE = 25, /* Wanpipe API Sockets */
|
|
||||||
AF_LLC = 26, /* Linux LLC */
|
|
||||||
AF_IB = 27, /* Native InfiniBand address */
|
|
||||||
AF_MPLS = 28, /* MPLS */
|
|
||||||
AF_CAN = 29, /* Controller Area Network */
|
|
||||||
AF_TIPC = 30, /* TIPC sockets */
|
|
||||||
AF_BLUETOOTH = 31, /* Bluetooth sockets */
|
|
||||||
AF_IUCV = 32, /* IUCV sockets */
|
|
||||||
AF_RXRPC = 33, /* RxRPC sockets */
|
|
||||||
AF_ISDN = 34, /* mISDN sockets */
|
|
||||||
AF_PHONET = 35, /* Phonet sockets */
|
|
||||||
AF_IEEE802154 = 36, /* IEEE802154 sockets */
|
|
||||||
AF_CAIF = 37, /* CAIF sockets */
|
|
||||||
AF_ALG = 38, /* Algorithm sockets */
|
|
||||||
AF_NFC = 39, /* NFC sockets */
|
|
||||||
AF_VSOCK = 40, /* vSockets */
|
|
||||||
AF_KCM = 41, /* Kernel Connection Multiplexor*/
|
|
||||||
AF_QIPCRTR = 42, /* Qualcomm IPC Router */
|
|
||||||
AF_SMC = 43, /* smc sockets: reserve number for
|
|
||||||
* PF_SMC protocol family that
|
|
||||||
* reuses AF_INET address family
|
|
||||||
*/
|
|
||||||
AF_XDP = 44, /* XDP sockets */
|
|
||||||
AF_MCTP = 45, /* Management component
|
|
||||||
* transport protocol
|
|
||||||
*/
|
|
||||||
AF_MAX = 46, /* For now.. */
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<InAddr> for Ipv4Address {
|
|
||||||
fn from(value: InAddr) -> Self {
|
|
||||||
let addr = value.as_bytes();
|
|
||||||
Ipv4Address::from_bytes(addr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Ipv4Address> for InAddr {
|
|
||||||
fn from(value: Ipv4Address) -> Self {
|
|
||||||
let bytes = value.as_bytes();
|
|
||||||
InAddr::from_bytes(bytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SockAddrIn> for SocketAddr {
|
|
||||||
fn from(value: SockAddrIn) -> Self {
|
|
||||||
let port = value.sin_port_t.as_u16();
|
|
||||||
let addr = Ipv4Address::from(value.sin_addr);
|
|
||||||
SocketAddr::IPv4(addr, port)
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user