diff --git a/cykusz-rs/src/kernel/net/dhcp.rs b/cykusz-rs/src/kernel/net/dhcp.rs index 6c7df7ce..064385c8 100644 --- a/cykusz-rs/src/kernel/net/dhcp.rs +++ b/cykusz-rs/src/kernel/net/dhcp.rs @@ -7,7 +7,7 @@ use core::marker::PhantomData; use syscall_defs::net::{NetU16, NetU32, NetU8}; use crate::kernel::net::ip::{Ip, Ip4}; -use crate::kernel::net::socket::SocketService; +use crate::kernel::net::socket::{NetSocketService, SocketService}; use crate::kernel::net::udp::Udp; use crate::kernel::net::{ default_driver, Packet, PacketDownHierarchy, PacketHeader, PacketKind, PacketUpHierarchy, @@ -433,7 +433,9 @@ fn process_packet_udp(packet: Packet) { struct DhcpService {} -impl SocketService for DhcpService { +impl SocketService for DhcpService {} + +impl NetSocketService for DhcpService { fn process_packet(&self, packet: Packet) { process_packet_udp(packet.upgrade()); } diff --git a/cykusz-rs/src/kernel/net/dns.rs b/cykusz-rs/src/kernel/net/dns.rs index 0c0cba6f..a597cc5d 100644 --- a/cykusz-rs/src/kernel/net/dns.rs +++ b/cykusz-rs/src/kernel/net/dns.rs @@ -5,7 +5,7 @@ use syscall_defs::net::NetU16; use crate::kernel::mm::VirtAddr; use crate::kernel::net::ip::{Ip, Ip4}; -use crate::kernel::net::socket::SocketService; +use crate::kernel::net::socket::{NetSocketService, SocketService}; use crate::kernel::net::udp::Udp; use crate::kernel::net::{ default_driver, Packet, PacketDownHierarchy, PacketHeader, PacketKind, PacketUpHierarchy, @@ -275,7 +275,9 @@ impl DnsService { } } -impl SocketService for DnsService { +impl SocketService for DnsService {} + +impl NetSocketService for DnsService { fn process_packet(&self, packet: Packet) { let udp_packet: Packet = packet.upgrade(); let mut packet: Packet = udp_packet.upgrade(); diff --git a/cykusz-rs/src/kernel/net/mod.rs b/cykusz-rs/src/kernel/net/mod.rs index 1015731e..d3ed6b06 100644 --- a/cykusz-rs/src/kernel/net/mod.rs +++ b/cykusz-rs/src/kernel/net/mod.rs @@ -27,6 +27,7 @@ pub mod packet; pub mod socket; pub mod tcp; pub mod udp; +pub mod unix; pub mod util; pub trait NetDriver: Sync + Send { diff --git a/cykusz-rs/src/kernel/net/socket.rs b/cykusz-rs/src/kernel/net/socket.rs index 5bd659c7..9eeec89b 100644 --- a/cykusz-rs/src/kernel/net/socket.rs +++ b/cykusz-rs/src/kernel/net/socket.rs @@ -1,7 +1,7 @@ use alloc::sync::Arc; use syscall_defs::net::{ - MsgFlags, MsgHdr, SockAddr, SockDomain, SockOption, SockType, SockTypeFlags, + MsgFlags, MsgHdr, SockAddrPtr, SockDomain, SockOption, SockType, SockTypeFlags, }; use syscall_defs::SyscallError::ENOTSUP; use syscall_defs::{SyscallError, SyscallResult}; @@ -11,40 +11,40 @@ use crate::kernel::net::ip::{Ip, Ip4}; use crate::kernel::net::Packet; pub fn new(domain: SockDomain, typ: SockTypeFlags) -> Result, SyscallError> { - if domain != SockDomain::AfInet { - return Err(SyscallError::ENOTSUP); - } - logln4!("new socket: {:?} {:?}", domain, SockType::from(typ)); - match SockType::from(typ) { - SockType::Stream => Ok(crate::kernel::net::tcp::socket::Socket::new_unbound()), - SockType::Dgram => Ok(crate::kernel::net::udp::socket::Socket::new_unbound()), + match (domain, SockType::from(typ)) { + (SockDomain::AfInet, SockType::Stream) => { + Ok(crate::kernel::net::tcp::socket::Socket::new_unbound()) + } + (SockDomain::AfInet, SockType::Dgram) => { + Ok(crate::kernel::net::udp::socket::Socket::new_unbound()) + } + (SockDomain::AfUnix, _st @ (SockType::Stream | SockType::Dgram)) => { + Ok(crate::kernel::net::unix::socket::Socket::new_unbound()) + } _ => Err(ENOTSUP), } } pub trait SocketService: Sync + Send { - fn process_packet(&self, packet: Packet); - fn port_unreachable(&self, port: u32, dst_port: u32); - fn listen(&self, _backlog: i32) -> SyscallResult { Err(SyscallError::EOPNOTSUPP) } fn accept( &self, - _sock_addr: Option<&mut SockAddr>, + _sock_addr: SockAddrPtr, _addrlen: Option<&mut u32>, ) -> Result, SyscallError> { Err(SyscallError::EOPNOTSUPP) } - fn bind(&self, _sock_addr: &SockAddr, _addrlen: u32) -> SyscallResult { + fn bind(&self, _sock_addr: SockAddrPtr, _addrlen: u32) -> SyscallResult { Err(SyscallError::EOPNOTSUPP) } - fn connect(&self, _sock_addr: &SockAddr, _addrlen: u32) -> SyscallResult { + fn connect(&self, _sock_addr: SockAddrPtr, _addrlen: u32) -> SyscallResult { Err(SyscallError::EOPNOTSUPP) } @@ -56,10 +56,6 @@ pub trait SocketService: Sync + Send { Err(SyscallError::EOPNOTSUPP) } - fn src_port(&self) -> u32; - fn target(&self) -> Ip4; - fn set_src_port(&self, _src_port: u32) {} - fn set_socket_option( &self, _layer: i32, @@ -84,3 +80,11 @@ pub trait SocketService: Sync + Send { None } } + +pub trait NetSocketService: SocketService { + fn process_packet(&self, packet: Packet); + fn port_unreachable(&self, port: u32, dst_port: u32); + fn src_port(&self) -> u32; + fn target(&self) -> Ip4; + fn set_src_port(&self, _src_port: u32) {} +} diff --git a/cykusz-rs/src/kernel/net/tcp/mod.rs b/cykusz-rs/src/kernel/net/tcp/mod.rs index 4d14e2f9..76efcc03 100644 --- a/cykusz-rs/src/kernel/net/tcp/mod.rs +++ b/cykusz-rs/src/kernel/net/tcp/mod.rs @@ -6,7 +6,7 @@ use bit_field::BitField; use syscall_defs::net::{NetU16, NetU32}; use crate::kernel::net::ip::{Ip, Ip4, IpHeader, IpType}; -use crate::kernel::net::socket::SocketService; +use crate::kernel::net::socket::NetSocketService; use crate::kernel::net::tcp::socket::TcpFlags; use crate::kernel::net::util::checksum; use crate::kernel::net::{ @@ -272,10 +272,10 @@ pub fn port_unreachable(port: u32, dst_port: u32, _dst_ip: Ip4) { } } -static HANDLERS: RwSpin>> = +static HANDLERS: RwSpin>> = RwSpin::new(BTreeMap::new()); -pub fn register_handler(handler: Arc) -> Option { +pub fn register_handler(handler: Arc) -> Option { let port = handler.src_port(); if port == 0 { let port = register_ephemeral_handler(handler)?; @@ -296,7 +296,7 @@ pub fn register_handler(handler: Arc) -> Option { None } -pub fn register_ephemeral_handler(handler: Arc) -> Option { +pub fn register_ephemeral_handler(handler: Arc) -> Option { let target = handler.target(); let mut handlers = HANDLERS.write(); diff --git a/cykusz-rs/src/kernel/net/tcp/socket.rs b/cykusz-rs/src/kernel/net/tcp/socket.rs index 7bb2eda8..8d54de01 100644 --- a/cykusz-rs/src/kernel/net/tcp/socket.rs +++ b/cykusz-rs/src/kernel/net/tcp/socket.rs @@ -1,7 +1,7 @@ use alloc::sync::{Arc, Weak}; use alloc::vec::Vec; -use syscall_defs::net::{MsgFlags, MsgHdr, SockAddr, SockAddrIn, SockOption}; +use syscall_defs::net::{MsgFlags, MsgHdr, SockAddrIn, SockAddrPtr, SockOption}; use syscall_defs::poll::PollEventFlags; use syscall_defs::stat::Stat; use syscall_defs::{OpenFlags, SyscallError, SyscallResult}; @@ -11,7 +11,7 @@ use crate::kernel::fs::poll::PollTable; use crate::kernel::fs::vfs::{FsError, Result}; use crate::kernel::mm::PAGE_SIZE; use crate::kernel::net::ip::{Ip, Ip4, IpHeader}; -use crate::kernel::net::socket::SocketService; +use crate::kernel::net::socket::{NetSocketService, SocketService}; use crate::kernel::net::tcp::{Tcp, TcpHeader}; use crate::kernel::net::{ default_driver, Packet, PacketDownHierarchy, PacketHeader, PacketTrait, PacketUpHierarchy, @@ -1061,31 +1061,6 @@ impl INode for Socket { } impl SocketService for Socket { - fn process_packet(&self, packet: Packet) { - logln5!("process packet start"); - let mut data = self.data.lock(); - logln5!("process packet locked"); - - if !data.is_listening() { - data.process(packet.upgrade(), &self.in_buffer); - - if data.state == State::Closed { - self.in_buffer.readers_queue().notify_all(); - } - } else { - if let Some(sock) = data.process_new_connection(packet.upgrade()) { - self.connections.lock().connections.push(sock); - self.connections_wq.notify_all(); - } - } - } - - fn port_unreachable(&self, _port: u32, dst_port: u32) { - println!("Failed to send to port {}", dst_port); - - self.data.lock().finalize(); - } - fn listen(&self, backlog: i32) -> SyscallResult { self.init(true); @@ -1098,7 +1073,7 @@ impl SocketService for Socket { fn accept( &self, - sock_addr: Option<&mut SockAddr>, + mut sock_addr: SockAddrPtr, _addrlen: Option<&mut u32>, ) -> core::result::Result, SyscallError> { let mut lock = self @@ -1108,33 +1083,34 @@ impl SocketService for Socket { })? .unwrap(); - if let Some(addr) = sock_addr { - *addr = SockAddrIn::new(self.dst_port(), self.target().into()).into_sock_addr(); + if !sock_addr.is_null() { + let addr = sock_addr.as_sock_addr_in_mut(); + *addr = SockAddrIn::new(self.dst_port(), self.target().into()); } Ok(lock.connections.pop().unwrap()) } - fn bind(&self, sock_addr: &SockAddr, addrlen: u32) -> SyscallResult { + fn bind(&self, sock_addr: SockAddrPtr, addrlen: u32) -> SyscallResult { logln5!("tcp bind"); - if addrlen as usize != core::mem::size_of::() { + let sock_addr = sock_addr.as_sock_addr_in(); + if addrlen as usize != core::mem::size_of::() { return Err(SyscallError::EINVAL); } - self.set_src_port(sock_addr.as_sock_addr_in().port()); + self.set_src_port(sock_addr.port()); Ok(0) } - fn connect(&self, sock_addr: &SockAddr, addrlen: u32) -> SyscallResult { + fn connect(&self, sock_addr: SockAddrPtr, addrlen: u32) -> SyscallResult { logln5!("tcp connect"); - if addrlen as usize != core::mem::size_of::() { + let sock_addr = sock_addr.as_sock_addr_in(); + if addrlen as usize != core::mem::size_of::() { return Err(SyscallError::EINVAL); } - let addr_in = sock_addr.as_sock_addr_in(); - - self.set_dst_port(addr_in.port()); - self.set_target(addr_in.sin_addr.s_addr.into()); + self.set_dst_port(sock_addr.port()); + self.set_target(sock_addr.sin_addr.s_addr.into()); self.in_buffer.init_size(PAGE_SIZE * 18); self.init(false); @@ -1191,18 +1167,6 @@ impl SocketService for Socket { return Ok(total); } - fn src_port(&self) -> u32 { - self.src_port() as u32 - } - - fn target(&self) -> Ip4 { - self.target() - } - - fn set_src_port(&self, src_port: u32) { - self.set_src_port(src_port as u16); - } - fn get_socket_option( &self, _layer: i32, @@ -1219,6 +1183,45 @@ impl SocketService for Socket { } } +impl NetSocketService for Socket { + fn process_packet(&self, packet: Packet) { + logln5!("process packet start"); + let mut data = self.data.lock(); + logln5!("process packet locked"); + + if !data.is_listening() { + data.process(packet.upgrade(), &self.in_buffer); + + if data.state == State::Closed { + self.in_buffer.readers_queue().notify_all(); + } + } else { + if let Some(sock) = data.process_new_connection(packet.upgrade()) { + self.connections.lock().connections.push(sock); + self.connections_wq.notify_all(); + } + } + } + + fn port_unreachable(&self, _port: u32, dst_port: u32) { + println!("Failed to send to port {}", dst_port); + + self.data.lock().finalize(); + } + + fn src_port(&self) -> u32 { + self.src_port() as u32 + } + + fn target(&self) -> Ip4 { + self.target() + } + + fn set_src_port(&self, src_port: u32) { + self.set_src_port(src_port as u16); + } +} + impl Drop for Socket { fn drop(&mut self) { self.data.lock().close(); diff --git a/cykusz-rs/src/kernel/net/udp/mod.rs b/cykusz-rs/src/kernel/net/udp/mod.rs index ff641d5e..ba791448 100644 --- a/cykusz-rs/src/kernel/net/udp/mod.rs +++ b/cykusz-rs/src/kernel/net/udp/mod.rs @@ -4,7 +4,7 @@ use alloc::sync::Arc; use syscall_defs::net::NetU16; use crate::kernel::net::ip::{Ip, Ip4, IpHeader, IpType}; -use crate::kernel::net::socket::SocketService; +use crate::kernel::net::socket::NetSocketService; use crate::kernel::net::util::checksum; use crate::kernel::net::{ ConstPacketKind, Packet, PacketDownHierarchy, PacketHeader, PacketUpHierarchy, @@ -109,9 +109,9 @@ pub fn port_unreachable(port: u32, dst_port: u32) { } } -static HANDLERS: RwSpin>> = RwSpin::new(BTreeMap::new()); +static HANDLERS: RwSpin>> = RwSpin::new(BTreeMap::new()); -pub fn register_handler(handler: Arc) -> Option { +pub fn register_handler(handler: Arc) -> Option { let port = handler.src_port(); if port == 0 { @@ -129,7 +129,7 @@ pub fn register_handler(handler: Arc) -> Option { None } -pub fn register_ephemeral_handler(handler: Arc) -> Option { +pub fn register_ephemeral_handler(handler: Arc) -> Option { let mut handlers = HANDLERS.write(); for p in 49152..=65535 { diff --git a/cykusz-rs/src/kernel/net/udp/socket.rs b/cykusz-rs/src/kernel/net/udp/socket.rs index 680a8129..3fe57aa2 100644 --- a/cykusz-rs/src/kernel/net/udp/socket.rs +++ b/cykusz-rs/src/kernel/net/udp/socket.rs @@ -5,7 +5,7 @@ use core::sync::atomic::AtomicBool; use core::sync::atomic::AtomicU32; use core::sync::atomic::Ordering; -use syscall_defs::net::{MsgFlags, MsgHdr, NetU16, SockAddr, SockOption}; +use syscall_defs::net::{MsgFlags, MsgHdr, NetU16, SockAddrIn, SockAddrPtr, SockOption}; use syscall_defs::poll::PollEventFlags; use syscall_defs::stat::Stat; use syscall_defs::{OpenFlags, SyscallError, SyscallResult}; @@ -14,7 +14,7 @@ use crate::kernel::fs::inode::INode; use crate::kernel::fs::poll::PollTable; use crate::kernel::fs::vfs::{FsError, Result}; use crate::kernel::net::ip::{Ip, Ip4}; -use crate::kernel::net::socket::SocketService; +use crate::kernel::net::socket::{NetSocketService, SocketService}; use crate::kernel::net::udp::Udp; use crate::kernel::net::{default_driver, Packet, PacketHeader, PacketTrait, PacketUpHierarchy}; use crate::kernel::sync::Spin; @@ -214,48 +214,29 @@ impl INode for Socket { } impl SocketService for Socket { - fn process_packet(&self, ip: Packet) { - let packet: Packet = ip.upgrade(); - - let ip_header = ip.header(); - let udp_header = packet.header(); - - let recv = RecvPacket::new( - udp_header.src_port.value() as u32, - ip_header.src_ip, - Vec::from(packet.data()), - ); - - self.buffer.lock().push_back(recv); - - self.buffer_wq.notify_all(); - } - - fn port_unreachable(&self, _port: u32, dst_port: u32) { - logln4!("UDP: Failed to send to port {}", dst_port); - } + fn bind(&self, sock_addr: SockAddrPtr, addrlen: u32) -> SyscallResult { + let sock_addr = sock_addr.as_sock_addr_in(); - fn bind(&self, sock_addr: &SockAddr, addrlen: u32) -> SyscallResult { - if addrlen as usize != core::mem::size_of::() { + if addrlen as usize != core::mem::size_of::() { return Err(SyscallError::EINVAL); } - self.set_src_port(sock_addr.as_sock_addr_in().port() as u32); + self.set_src_port(sock_addr.port() as u32); crate::kernel::net::udp::register_handler(self.me()); return Ok(0); } - fn connect(&self, sock_addr: &SockAddr, addrlen: u32) -> SyscallResult { - if addrlen as usize != core::mem::size_of::() { + fn connect(&self, sock_addr: SockAddrPtr, addrlen: u32) -> SyscallResult { + let sock_addr = sock_addr.as_sock_addr_in(); + + if addrlen as usize != core::mem::size_of::() { return Err(SyscallError::EINVAL); } - let addr_in = sock_addr.as_sock_addr_in(); - - self.set_dst_port(addr_in.port() as u32); - self.set_dst_ip(addr_in.sin_addr.s_addr.into()); + self.set_dst_port(sock_addr.port() as u32); + self.set_dst_ip(sock_addr.sin_addr.s_addr.into()); if self.src_port() == 0 { crate::kernel::net::udp::register_handler(self.me()); @@ -266,9 +247,8 @@ impl SocketService for Socket { fn msg_send(&self, hdr: &MsgHdr, _flags: MsgFlags) -> SyscallResult { logln5!("UDP msg_send???"); - let dest = if let Some(addr) = hdr.sock_addr() { - let addr_in = addr.as_sock_addr_in(); - Some((addr_in.port() as u32, addr_in.sin_addr.s_addr.into())) + let dest = if let Some(addr) = hdr.sock_addr_in() { + Some((addr.port() as u32, addr.sin_addr.s_addr.into())) } else { None }; @@ -300,8 +280,7 @@ impl SocketService for Socket { drop(data); - if let Some(addr) = hdr.sock_addr_mut() { - let addr = addr.as_sock_addr_in_mut(); + if let Some(addr) = hdr.sock_addr_in_mut() { addr.sin_port = NetU16::new(packet.src_port() as u16); addr.sin_addr.s_addr = packet.src_ip().into(); } @@ -321,18 +300,6 @@ impl SocketService for Socket { .sum::()) } - fn src_port(&self) -> u32 { - self.src_port() - } - - fn target(&self) -> Ip4 { - self.dst_ip().unwrap() - } - - fn set_src_port(&self, src_port: u32) { - self.set_src_port(src_port); - } - fn set_socket_option( &self, _layer: i32, @@ -347,3 +314,38 @@ impl SocketService for Socket { Some(self.self_ref.upgrade()?) } } + +impl NetSocketService for Socket { + fn process_packet(&self, ip: Packet) { + let packet: Packet = ip.upgrade(); + + let ip_header = ip.header(); + let udp_header = packet.header(); + + let recv = RecvPacket::new( + udp_header.src_port.value() as u32, + ip_header.src_ip, + Vec::from(packet.data()), + ); + + self.buffer.lock().push_back(recv); + + self.buffer_wq.notify_all(); + } + + fn port_unreachable(&self, _port: u32, dst_port: u32) { + logln4!("UDP: Failed to send to port {}", dst_port); + } + + fn src_port(&self) -> u32 { + self.src_port() + } + + fn target(&self) -> Ip4 { + self.dst_ip().unwrap() + } + + fn set_src_port(&self, src_port: u32) { + self.set_src_port(src_port); + } +} diff --git a/cykusz-rs/src/kernel/net/unix/mod.rs b/cykusz-rs/src/kernel/net/unix/mod.rs new file mode 100644 index 00000000..d22cc845 --- /dev/null +++ b/cykusz-rs/src/kernel/net/unix/mod.rs @@ -0,0 +1 @@ +pub mod socket; diff --git a/cykusz-rs/src/kernel/net/unix/socket.rs b/cykusz-rs/src/kernel/net/unix/socket.rs new file mode 100644 index 00000000..97fd3c9e --- /dev/null +++ b/cykusz-rs/src/kernel/net/unix/socket.rs @@ -0,0 +1,19 @@ +use crate::kernel::fs::inode::INode; +use crate::kernel::net::socket::SocketService; +use alloc::sync::{Arc, Weak}; + +pub struct Socket { + self_ref: Weak, +} + +impl Socket { + pub fn new_unbound() -> Arc { + Arc::new_cyclic(|me| Socket { + self_ref: me.clone(), + }) + } +} + +impl SocketService for Socket {} + +impl INode for Socket {} diff --git a/cykusz-rs/src/kernel/syscall/sys.rs b/cykusz-rs/src/kernel/syscall/sys.rs index 4677efdb..a81c7bb6 100644 --- a/cykusz-rs/src/kernel/syscall/sys.rs +++ b/cykusz-rs/src/kernel/syscall/sys.rs @@ -3,7 +3,7 @@ use alloc::sync::Arc; use alloc::sync::Weak; use alloc::vec::Vec; -use syscall_defs::net::{MsgFlags, MsgHdr, SockAddr, SockDomain, SockOption, SockTypeFlags}; +use syscall_defs::net::{MsgFlags, MsgHdr, SockAddrPtr, SockDomain, SockOption, SockTypeFlags}; use syscall_defs::poll::{FdSet, PollEventFlags}; use syscall_defs::signal::SigAction; use syscall_defs::stat::Mode; @@ -795,7 +795,7 @@ fn get_socket(fd: usize) -> Result, SyscallError> { pub fn sys_bind(sockfd: u64, addr_ptr: u64, addrlen: u64) -> SyscallResult { let sock = get_socket(sockfd as usize)?; - let addr = unsafe { VirtAddr(addr_ptr as usize).read_ref::() }; + let addr = SockAddrPtr::new(addr_ptr as *mut ()); sock.bind(addr, addrlen as u32) } @@ -803,7 +803,7 @@ pub fn sys_bind(sockfd: u64, addr_ptr: u64, addrlen: u64) -> SyscallResult { pub fn sys_connect(sockfd: u64, addr_ptr: u64, addrlen: u64) -> SyscallResult { let sock = get_socket(sockfd as usize)?; - let addr = unsafe { VirtAddr(addr_ptr as usize).read_ref::() }; + let addr = SockAddrPtr::new(addr_ptr as *mut ()); sock.connect(addr, addrlen as u32) } @@ -814,12 +814,12 @@ pub fn sys_accept(fd: u64, addr_ptr: u64, addr_len: u64) -> SyscallResult { let (ptr, len) = if addr_ptr != 0 && addr_len != 0 { unsafe { ( - Some(VirtAddr(addr_ptr as usize).read_mut::()), + SockAddrPtr::new(addr_ptr as *mut ()), Some(VirtAddr(addr_len as usize).read_mut::()), ) } } else { - (None, None) + (SockAddrPtr::new(core::ptr::null_mut()), None) }; let sock = sock.accept(ptr, len)?; diff --git a/syscall-defs/src/ioctl/net.rs b/syscall-defs/src/ioctl/net.rs index af25a166..0d250f4f 100644 --- a/syscall-defs/src/ioctl/net.rs +++ b/syscall-defs/src/ioctl/net.rs @@ -36,6 +36,7 @@ bitflags! { } } #[repr(C)] +#[derive(Copy, Clone)] pub union IfReqU { pub ifr_addr: SockAddr, pub ifr_dstaddr: SockAddr, diff --git a/syscall-defs/src/net.rs b/syscall-defs/src/net.rs index 8f7ba8d2..4578560a 100644 --- a/syscall-defs/src/net.rs +++ b/syscall-defs/src/net.rs @@ -124,21 +124,44 @@ impl TryFrom for SockDomain { } } } +pub struct SockAddrPtr(*mut ()); #[repr(C)] -#[derive(Default, Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub struct SockAddr { pub sa_family: SockDomain, pub sa_data: [u8; 14], } +impl SockAddrPtr { + pub fn new(addr: *mut ()) -> SockAddrPtr { + SockAddrPtr(addr) + } + + pub fn as_sock_addr_in(&self) -> &SockAddrIn { + unsafe { &*(self.0 as *const SockAddrIn) } + } + + pub fn as_sock_addr_in_mut(&mut self) -> &mut SockAddrIn { + unsafe { &mut *(self.0 as *mut SockAddrIn) } + } + + pub fn is_null(&self) -> bool { + self.0 == core::ptr::null_mut() + } + + pub fn addr(&self) -> usize { + self.0 as usize + } +} + impl SockAddr { pub fn as_sock_addr_in(&self) -> &SockAddrIn { - unsafe { core::mem::transmute::<&SockAddr, &SockAddrIn>(self) } + unsafe { &*(self as *const _ as *const SockAddrIn) } } pub fn as_sock_addr_in_mut(&mut self) -> &mut SockAddrIn { - unsafe { core::mem::transmute::<&mut SockAddr, &mut SockAddrIn>(self) } + unsafe { &mut *(self as *mut _ as *mut SockAddrIn) } } } @@ -179,10 +202,6 @@ impl SockAddrIn { ..Default::default() } } - - pub fn into_sock_addr(self) -> SockAddr { - unsafe { core::mem::transmute::(self) } - } } impl SockAddrIn { @@ -191,6 +210,28 @@ impl SockAddrIn { } } +#[repr(C)] +pub struct SockAddrUn { + pub sin_family: SockDomain, + pub sun_path: [u8; 108], +} + +impl SockAddrUn { + pub fn new(path: &str) -> Result { + let mut addr = SockAddrUn { + sin_family: SockDomain::AfUnix, + sun_path: [0u8; 108], + }; + let path = path.as_bytes(); + if path.len() >= 108 { + return Err(SyscallError::EACCES); + } + addr.sun_path[..path.len()].copy_from_slice(path); + + Ok(addr) + } +} + #[repr(C)] pub struct IpMreq { pub imr_multiaddr: InAddr, @@ -256,7 +297,7 @@ impl IoVec { #[repr(C)] pub struct MsgHdr { - pub msg_name: *const (), + pub msg_name: SockAddrPtr, pub msg_namelen: u32, pub msg_iov: *const IoVec, pub msg_iovlen: i32, @@ -276,21 +317,21 @@ impl MsgHdr { unsafe { core::slice::from_raw_parts(self.msg_iov, self.msg_iovlen as usize) } } - pub fn sock_addr(&self) -> Option<&SockAddr> { - if self.msg_name != core::ptr::null() - && self.msg_namelen as usize == core::mem::size_of::() + pub fn sock_addr_in(&self) -> Option<&SockAddrIn> { + if !self.msg_name.is_null() + && self.msg_namelen as usize == core::mem::size_of::() { - unsafe { (self.msg_name as *const SockAddr).as_ref() } + Some(self.msg_name.as_sock_addr_in()) } else { None } } - pub fn sock_addr_mut(&mut self) -> Option<&mut SockAddr> { - if self.msg_name != core::ptr::null() - && self.msg_namelen as usize == core::mem::size_of::() + pub fn sock_addr_in_mut(&mut self) -> Option<&mut SockAddrIn> { + if !self.msg_name.is_null() + && self.msg_namelen as usize == core::mem::size_of::() { - unsafe { (self.msg_name as *mut SockAddr).as_mut() } + Some(self.msg_name.as_sock_addr_in_mut()) } else { None } diff --git a/userspace/shell/src/nc.rs b/userspace/shell/src/nc.rs index 1c012468..319649ff 100644 --- a/userspace/shell/src/nc.rs +++ b/userspace/shell/src/nc.rs @@ -1,5 +1,5 @@ use std::ptr::addr_of_mut; -use syscall_defs::net::{SockAddr, SockAddrIn, SockDomain, SockType, SockTypeFlags}; +use syscall_defs::net::{SockAddrPtr, SockAddrIn, SockDomain, SockType, SockTypeFlags}; use syscall_defs::poll::FdSet; use syscall_user as syscall; @@ -104,12 +104,12 @@ pub fn connect(port: u32, ip: &[u8]) { ) .unwrap(); - let addr = SockAddrIn::from_array(port as u16, ip); + let mut addr = SockAddrIn::from_array(port as u16, ip); if let Ok(_) = syscall::connect( sock, - &addr.into_sock_addr(), - core::mem::size_of::(), + SockAddrPtr::new(&mut addr as *mut _ as *mut ()), + core::mem::size_of::(), ) { start(sock); } else { @@ -124,18 +124,18 @@ pub fn bind(src_port: u32) { ) .unwrap(); - let addr = SockAddrIn::from_array(src_port as u16, &[0, 0, 0, 0]); + let mut addr = SockAddrIn::from_array(src_port as u16, &[0, 0, 0, 0]); if let Ok(_) = syscall::bind( sock, - &addr.into_sock_addr(), - core::mem::size_of::(), + SockAddrPtr::new(&mut addr as *mut _ as *mut ()), + core::mem::size_of::(), ) { if syscall::listen(sock, 5).is_err() { println!("Listen failed"); return; }; - if let Ok(new_fd) = syscall::accept(sock, None, None) { + if let Ok(new_fd) = syscall::accept(sock, SockAddrPtr::new(core::ptr::null_mut()), None) { println!("new fd: {}", new_fd); start(new_fd); } diff --git a/userspace/syscall-user/src/lib.rs b/userspace/syscall-user/src/lib.rs index 8e41999e..0cfab035 100644 --- a/userspace/syscall-user/src/lib.rs +++ b/userspace/syscall-user/src/lib.rs @@ -6,7 +6,7 @@ pub mod print; use std::arch::asm; use std::sync::atomic::AtomicU32; -use syscall_defs::net::{MsgHdr, SockAddr, SockDomain, SockTypeFlags}; +use syscall_defs::net::{MsgHdr, SockAddrPtr, SockDomain, SockTypeFlags}; use syscall_defs::poll::FdSet; use syscall_defs::signal::SigAction; use syscall_defs::time::Timespec; @@ -291,24 +291,20 @@ pub fn socket(domain: SockDomain, typ: SockTypeFlags) -> SyscallResult { unsafe { syscall2(SYS_SOCKET, domain as usize, typ.into()) } } -pub fn bind(fd: usize, addr: &SockAddr, addr_len: usize) -> SyscallResult { - unsafe { syscall3(SYS_BIND, fd, addr as *const _ as usize, addr_len) } +pub fn bind(fd: usize, addr: SockAddrPtr, addr_len: usize) -> SyscallResult { + unsafe { syscall3(SYS_BIND, fd, addr.addr(), addr_len) } } -pub fn connect(fd: usize, addr: &SockAddr, addr_len: usize) -> SyscallResult { - unsafe { syscall3(SYS_CONNECT, fd, addr as *const _ as usize, addr_len) } +pub fn connect(fd: usize, addr: SockAddrPtr, addr_len: usize) -> SyscallResult { + unsafe { syscall3(SYS_CONNECT, fd, addr.addr(), addr_len) } } -pub fn accept(fd: usize, addr: Option<&mut SockAddr>, len: Option<&mut usize>) -> SyscallResult { +pub fn accept(fd: usize, addr: SockAddrPtr, len: Option<&mut usize>) -> SyscallResult { unsafe { syscall3( SYS_ACCEPT, fd, - if let Some(a) = addr { - a as *mut SockAddr as usize - } else { - 0 - }, + addr.addr(), if let Some(l) = len { l as *mut _ as usize } else {