Browse Source

纸糊忙等tcp connecting,尚不明确连接可用的机制。

Samuka007 4 months ago
parent
commit
f438808421

+ 7 - 8
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 {

+ 1 - 1
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)));

+ 1 - 0
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())
     }
 

+ 5 - 5
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<BTreeMap<usize, Arc<dyn Iface>>> = NET_DEVICES.read_irqsave();
     if guard.len() == 0 {
         warn!("poll_ifaces: No net driver found!");

+ 2 - 4
kernel/src/net/socket/family.rs

@@ -106,10 +106,8 @@ impl core::convert::TryFrom<u16> for AddressFamily {
     type Error = system_error::SystemError;
     fn try_from(x: u16) -> Result<Self, Self::Error> {
         use num_traits::FromPrimitive;
-        return <Self as FromPrimitive>::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 <Self as FromPrimitive>::from_u16(x).ok_or(Self::Error::EINVAL);
     }
 }
 

+ 1 - 1
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;
     }
 

+ 14 - 9
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<SystemError>) {
+    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,

+ 102 - 68
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<Self> {
+    pub fn new(_nonblock: bool, ver: smoltcp::wire::IpVersion) -> Arc<Self> {
         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<TcpSocket>, 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<usize, SystemError> {
@@ -194,20 +205,23 @@ impl TcpSocket {
     }
 
     pub fn try_send(&self, buf: &[u8]) -> Result<usize, SystemError> {
-        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<Inode>, 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> {