diff --git a/kernel/src/arch/x86_64/syscall/mod.rs b/kernel/src/arch/x86_64/syscall/mod.rs index 4cb57d08..2e26a248 100644 --- a/kernel/src/arch/x86_64/syscall/mod.rs +++ b/kernel/src/arch/x86_64/syscall/mod.rs @@ -104,33 +104,32 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) { ]; mfence(); let pid = ProcessManager::current_pcb().pid(); - let mut show = - (syscall_num != SYS_SCHED) && (pid.data() >= 7); - // false; + let mut show = (syscall_num != SYS_SCHED) && (pid.data() >= 7); + // false; let to_print = SysCall::try_from(syscall_num); if let Ok(to_print) = to_print { use SysCall::*; match to_print { SYS_ACCEPT | SYS_ACCEPT4 | SYS_BIND | SYS_CONNECT | SYS_SHUTDOWN | SYS_LISTEN => { - show &= false; + // show &= false; } SYS_RECVFROM | SYS_SENDTO | SYS_SENDMSG | SYS_RECVMSG => { - show &= false; + // show &= false; } SYS_SOCKET | SYS_GETSOCKNAME | SYS_GETPEERNAME | SYS_SOCKETPAIR | SYS_SETSOCKOPT | SYS_GETSOCKOPT => { - show &= false; + // show &= false; } SYS_OPEN | SYS_OPENAT | SYS_CREAT | SYS_CLOSE => { - show &= false; + // show &= false; } SYS_READ | SYS_WRITE | SYS_READV | SYS_WRITEV | SYS_PREAD64 | SYS_PWRITE64 | SYS_PREADV | SYS_PWRITEV | SYS_PREADV2 => { show &= false; } _ => { - show &= false; + // show &= false; } } if show { diff --git a/kernel/src/driver/net/mod.rs b/kernel/src/driver/net/mod.rs index 7b26906f..fa5bc0d1 100644 --- a/kernel/src/driver/net/mod.rs +++ b/kernel/src/driver/net/mod.rs @@ -246,8 +246,8 @@ impl IfaceCommon { self.bounds.read().iter().for_each(|bound_socket| { // incase our inet socket missed the event, we manually notify it each time we poll - bound_socket.on_iface_events(); if has_events { + bound_socket.on_iface_events(); bound_socket .wait_queue() .wakeup(Some(ProcessState::Blocked(true))); diff --git a/kernel/src/driver/net/virtio_net.rs b/kernel/src/driver/net/virtio_net.rs index fde2023f..27d544ec 100644 --- a/kernel/src/driver/net/virtio_net.rs +++ b/kernel/src/driver/net/virtio_net.rs @@ -645,6 +645,7 @@ impl Iface for VirtioInterface { } fn poll(&self) { + // log::debug!("VirtioInterface: poll"); self.iface_common.poll(self.device_inner.force_get_mut()) } diff --git a/kernel/src/net/net_core.rs b/kernel/src/net/net_core.rs index 0f1e67ab..142fbf84 100644 --- a/kernel/src/net/net_core.rs +++ b/kernel/src/net/net_core.rs @@ -42,7 +42,7 @@ pub fn net_init() -> Result<(), SystemError> { fn dhcp_query() -> Result<(), SystemError> { let binding = NET_DEVICES.write_irqsave(); - log::debug!("binding: {:?}", *binding); + // log::debug!("binding: {:?}", *binding); //由于现在os未实现在用户态为网卡动态分配内存,而lo网卡的id最先分配且ip固定不能被分配 //所以特判取用id为1的网卡(也就是virtio_net) let net_face = binding.get(&1).ok_or(SystemError::ENODEV)?.clone(); @@ -63,7 +63,7 @@ fn dhcp_query() -> Result<(), SystemError> { // let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket); let dhcp_handle = sockets().add(dhcp_socket); - const DHCP_TRY_ROUND: u8 = 10; + const DHCP_TRY_ROUND: u8 = 100; for i in 0..DHCP_TRY_ROUND { log::debug!("DHCP try round: {}", i); net_face.poll(); @@ -137,8 +137,8 @@ fn dhcp_query() -> Result<(), SystemError> { drop(binding); let sleep_time = PosixTimeSpec { - tv_sec: 5, - tv_nsec: 0, + tv_sec: 0, + tv_nsec: 50, }; let _ = nanosleep(sleep_time)?; } @@ -147,7 +147,7 @@ fn dhcp_query() -> Result<(), SystemError> { } pub fn poll_ifaces() { - // log::debug!("poll_ifaces"); + log::debug!("poll_ifaces"); let guard: RwLockReadGuard>> = NET_DEVICES.read_irqsave(); if guard.len() == 0 { warn!("poll_ifaces: No net driver found!"); diff --git a/kernel/src/net/socket/family.rs b/kernel/src/net/socket/family.rs index 3a17feb0..d753d25c 100644 --- a/kernel/src/net/socket/family.rs +++ b/kernel/src/net/socket/family.rs @@ -106,10 +106,8 @@ impl core::convert::TryFrom for AddressFamily { type Error = system_error::SystemError; fn try_from(x: u16) -> Result { use num_traits::FromPrimitive; - return ::from_u16(x).ok_or({ - log::debug!("AddressFamily::try_from failed: x={}", x); - Self::Error::EINVAL - }); + // this will return EINVAL but still works, idk why + return ::from_u16(x).ok_or(Self::Error::EINVAL); } } diff --git a/kernel/src/net/socket/inet/datagram/mod.rs b/kernel/src/net/socket/inet/datagram/mod.rs index f6b3b406..44bb9bb2 100644 --- a/kernel/src/net/socket/inet/datagram/mod.rs +++ b/kernel/src/net/socket/inet/datagram/mod.rs @@ -84,11 +84,11 @@ impl UdpSocket { &self, buf: &mut [u8], ) -> Result<(usize, smoltcp::wire::IpEndpoint), SystemError> { - poll_ifaces(); let received = match self.inner.read().as_ref().expect("Udp Inner is None") { UdpInner::Bound(bound) => bound.try_recv(buf), _ => Err(ENOTCONN), }; + poll_ifaces(); return received; } diff --git a/kernel/src/net/socket/inet/stream/inner.rs b/kernel/src/net/socket/inet/stream/inner.rs index 36b32313..9f658b5f 100644 --- a/kernel/src/net/socket/inet/stream/inner.rs +++ b/kernel/src/net/socket/inet/stream/inner.rs @@ -207,16 +207,20 @@ impl Connecting { self.inner.with_mut(f) } - pub fn into_result(self) -> (Inner, Option) { + pub fn into_result(self) -> (Inner, Result<(), SystemError>) { use ConnectResult::*; let result = *self.result.read_irqsave(); match result { - Connecting => (Inner::Connecting(self), Some(EAGAIN_OR_EWOULDBLOCK)), - Connected => (Inner::Established(Established { inner: self.inner }), None), - Refused => (Inner::Init(Init::new_bound(self.inner)), Some(ECONNREFUSED)), + Connecting => (Inner::Connecting(self), Err(EAGAIN_OR_EWOULDBLOCK)), + Connected => (Inner::Established(Established { inner: self.inner }), Ok(())), + Refused => (Inner::Init(Init::new_bound(self.inner)), Err(ECONNREFUSED)), } } + pub unsafe fn into_established(self) -> Established { + Established { inner: self.inner } + } + /// Returns `true` when `conn_result` becomes ready, which indicates that the caller should /// invoke the `into_result()` method as soon as possible. /// @@ -224,9 +228,9 @@ impl Connecting { /// _exactly_ once. The caller is responsible for not missing this event. #[must_use] pub(super) fn update_io_events(&self) -> bool { - if matches!(*self.result.read_irqsave(), ConnectResult::Connecting) { - return false; - } + // if matches!(*self.result.read_irqsave(), ConnectResult::Connecting) { + // return false; + // } self.inner .with_mut(|socket: &mut smoltcp::socket::tcp::Socket| { @@ -237,11 +241,14 @@ impl Connecting { // Connected if socket.can_send() { + log::debug!("can send"); *result = ConnectResult::Connected; return true; } // Connecting if socket.is_open() { + log::debug!("connecting"); + *result = ConnectResult::Connecting; return false; } // Refused @@ -309,7 +316,6 @@ impl Listening { }); if let Some(position) = position { - // log::debug!("Can accept!"); self.connect .store(position, core::sync::atomic::Ordering::Relaxed); pollee.fetch_or( @@ -317,7 +323,6 @@ impl Listening { core::sync::atomic::Ordering::Relaxed, ); } else { - // log::debug!("Can't accept!"); pollee.fetch_and( !EPollEventType::EPOLLIN.bits() as usize, core::sync::atomic::Ordering::Relaxed, diff --git a/kernel/src/net/socket/inet/stream/mod.rs b/kernel/src/net/socket/inet/stream/mod.rs index 935a93fa..ac00eb90 100644 --- a/kernel/src/net/socket/inet/stream/mod.rs +++ b/kernel/src/net/socket/inet/stream/mod.rs @@ -4,7 +4,6 @@ use system_error::SystemError::{self, *}; use crate::libs::rwlock::RwLock; use crate::net::event_poll::EPollEventType; -use crate::net::net_core::poll_ifaces; use crate::net::socket::*; use crate::sched::SchedMode; use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT_V4, UNSPECIFIED_LOCAL_ENDPOINT_V6}; @@ -29,14 +28,14 @@ pub struct TcpSocket { } impl TcpSocket { - pub fn new(nonblock: bool, ver: smoltcp::wire::IpVersion) -> Arc { + pub fn new(_nonblock: bool, ver: smoltcp::wire::IpVersion) -> Arc { Arc::new_cyclic(|me| Self { inner: RwLock::new(Some(Inner::Init(Init::new(ver)))), shutdown: Shutdown::new(), - nonblock: AtomicBool::new(nonblock), + nonblock: AtomicBool::new(false), wait_queue: WaitQueue::default(), self_ref: me.clone(), - pollee: AtomicUsize::new((EP::EPOLLIN.bits() | EP::EPOLLOUT.bits()) as usize), + pollee: AtomicUsize::new(0_usize), }) } @@ -100,7 +99,7 @@ impl TcpSocket { } pub fn try_accept(&self) -> Result<(Arc, smoltcp::wire::IpEndpoint), SystemError> { - poll_ifaces(); + // poll_ifaces(); match self.inner.write().as_mut().expect("Tcp Inner is None") { Inner::Listening(listening) => listening.accept().map(|(stream, remote)| { ( @@ -112,46 +111,48 @@ impl TcpSocket { } } + // SHOULD refactor pub fn start_connect( &self, remote_endpoint: smoltcp::wire::IpEndpoint, ) -> Result<(), SystemError> { let mut writer = self.inner.write(); let inner = writer.take().expect("Tcp Inner is None"); - let (init, err) = match inner { + let (init, result) = match inner { Inner::Init(init) => { let conn_result = init.connect(remote_endpoint); match conn_result { Ok(connecting) => ( Inner::Connecting(connecting), - if self.is_nonblock() { - None + if !self.is_nonblock() { + Ok(()) } else { - Some(EINPROGRESS) + Err(EINPROGRESS) }, ), - Err((init, err)) => (Inner::Init(init), Some(err)), + Err((init, err)) => (Inner::Init(init), Err(err)), } } Inner::Connecting(connecting) if self.is_nonblock() => { - (Inner::Connecting(connecting), Some(EALREADY)) + (Inner::Connecting(connecting), Err(EALREADY)) } - Inner::Connecting(connecting) => (Inner::Connecting(connecting), None), - Inner::Listening(inner) => (Inner::Listening(inner), Some(EISCONN)), - Inner::Established(inner) => (Inner::Established(inner), Some(EISCONN)), + Inner::Connecting(connecting) => (Inner::Connecting(connecting), Ok(())), + Inner::Listening(inner) => (Inner::Listening(inner), Err(EISCONN)), + Inner::Established(inner) => (Inner::Established(inner), Err(EISCONN)), }; - writer.replace(init); - drop(writer); - - poll_ifaces(); - - if let Some(err) = err { - return Err(err); + match result { + Ok(()) | Err(EINPROGRESS) => { + init.iface().unwrap().poll(); + }, + _ => {} } - return Ok(()); + + writer.replace(init); + return result; } + // for irq use pub fn finish_connect(&self) -> Result<(), SystemError> { let mut writer = self.inner.write(); let Inner::Connecting(conn) = writer.take().expect("Tcp Inner is None") else { @@ -159,22 +160,32 @@ impl TcpSocket { return Err(EINVAL); }; - let (inner, err) = conn.into_result(); + let (inner, result) = conn.into_result(); writer.replace(inner); drop(writer); - if let Some(err) = err { - return Err(err); - } - return Ok(()); + result } pub fn check_connect(&self) -> Result<(), SystemError> { - match self.inner.read().as_ref().expect("Tcp Inner is None") { - Inner::Connecting(_) => Err(EAGAIN_OR_EWOULDBLOCK), - Inner::Established(_) => Ok(()), // TODO check established - _ => Err(EINVAL), // TODO socket error options - } + self.update_events(); + let mut write_state = self.inner.write(); + let inner = write_state.take().expect("Tcp Inner is None"); + let (replace, result) = match inner { + Inner::Connecting(conn) => { + conn.into_result() + } + Inner::Established(es) => { + log::warn!("TODO: check new established"); + (Inner::Established(es), Ok(())) + }, // TODO check established + _ => { + log::warn!("TODO: connecting socket error options"); + (inner, Err(EINVAL)) + }, // TODO socket error options + }; + write_state.replace(replace); + result } pub fn try_recv(&self, buf: &mut [u8]) -> Result { @@ -194,20 +205,23 @@ impl TcpSocket { } pub fn try_send(&self, buf: &[u8]) -> Result { - match self.inner.read().as_ref().expect("Tcp Inner is None") { + // TODO: add nonblock check of connecting socket + let sent = match self.inner.read().as_ref().expect("Tcp Inner is None") { Inner::Established(inner) => { - let sent = inner.send_slice(buf); - poll_ifaces(); - sent + inner.send_slice(buf) } _ => Err(EINVAL), - } + }; + self.inner.read().as_ref().unwrap().iface().unwrap().poll(); + sent } fn update_events(&self) -> bool { match self.inner.read().as_ref().expect("Tcp Inner is None") { Inner::Init(_) => false, - Inner::Connecting(connecting) => connecting.update_io_events(), + Inner::Connecting(connecting) => { + connecting.update_io_events() + }, Inner::Established(established) => { established.update_io_events(&self.pollee); false @@ -219,12 +233,16 @@ impl TcpSocket { } } - // should only call on accept - fn is_acceptable(&self) -> bool { - // (self.poll() & EP::EPOLLIN.bits() as usize) != 0 - self.inner.read().as_ref().unwrap().iface().unwrap().poll(); + fn in_notify(&self) -> bool { + self.update_events(); + // shouldn't pollee but just get the status of the socket EP::from_bits_truncate(self.poll() as u32).contains(EP::EPOLLIN) } + + fn out_notify(&self) -> bool { + self.update_events(); + EP::from_bits_truncate(self.poll() as u32).contains(EP::EPOLLOUT) + } } impl Socket for TcpSocket { @@ -254,10 +272,18 @@ impl Socket for TcpSocket { } fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> { - if let Endpoint::Ip(addr) = endpoint { - return self.start_connect(addr); + let Endpoint::Ip(endpoint) = endpoint else { + log::debug!("TcpSocket::connect: invalid endpoint"); + return Err(EINVAL); + }; + self.start_connect(endpoint)?; // Only Nonblock or error will return error. + + return loop { + match self.check_connect() { + Err(EAGAIN_OR_EWOULDBLOCK) => {}, + result => break result, + } } - return Err(EINVAL); } fn poll(&self) -> usize { @@ -269,15 +295,17 @@ impl Socket for TcpSocket { } fn accept(&self) -> Result<(Arc, Endpoint), SystemError> { - // could block io if self.is_nonblock() { self.try_accept() } else { loop { - // log::debug!("TcpSocket::accept: wake up"); match self.try_accept() { Err(EAGAIN_OR_EWOULDBLOCK) => { - wq_wait_event_interruptible!(self.wait_queue, self.is_acceptable(), {})?; + wq_wait_event_interruptible!( + self.wait_queue, + self.in_notify(), + {} + )?; } result => break result, } @@ -311,26 +339,32 @@ impl Socket for TcpSocket { } fn close(&self) -> Result<(), SystemError> { - self.inner - .read() - .as_ref() - .map(|inner| match inner { - Inner::Connecting(_) => Err(EINPROGRESS), - Inner::Established(es) => { - es.close(); - es.release(); - Ok(()) - } - Inner::Listening(ls) => { - ls.close(); - Ok(()) - } - Inner::Init(init) => { - init.close(); - Ok(()) - } - }) - .unwrap_or(Ok(())) + let inner = self.inner + .write() + .take().unwrap(); + + match inner { + // complete connecting socket close logic + Inner::Connecting(conn) => { + let conn = unsafe { conn.into_established() }; + conn.close(); + conn.release(); + Ok(()) + }, + Inner::Established(es) => { + es.close(); + es.release(); + Ok(()) + } + Inner::Listening(ls) => { + ls.close(); + Ok(()) + } + Inner::Init(init) => { + init.close(); + Ok(()) + } + } } fn set_option(&self, level: PSOL, name: usize, val: &[u8]) -> Result<(), SystemError> {