diff --git a/kernel/src/driver/net/mod.rs b/kernel/src/driver/net/mod.rs index 80f09dd54..4b3cfe0f3 100644 --- a/kernel/src/driver/net/mod.rs +++ b/kernel/src/driver/net/mod.rs @@ -285,6 +285,14 @@ impl IfaceCommon { self.bounds.write().push(socket); } + pub fn unbind_socket(&self, socket: Arc) { + let mut bounds = self.bounds.write(); + if let Some(index) = bounds.iter().position(|s| Arc::ptr_eq(s, &socket)) { + bounds.remove(index); + log::debug!("unbind socket success"); + } + } + // TODO: 需要在inet实现多网卡监听或路由子系统实现后移除 pub fn is_default_iface(&self) -> bool { self.default_iface diff --git a/kernel/src/net/net_core.rs b/kernel/src/net/net_core.rs index 142fbf843..133efac86 100644 --- a/kernel/src/net/net_core.rs +++ b/kernel/src/net/net_core.rs @@ -60,8 +60,10 @@ fn dhcp_query() -> Result<(), SystemError> { let sockets = || net_face.sockets().lock_irqsave(); - // let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket); let dhcp_handle = sockets().add(dhcp_socket); + defer::defer!({ + sockets().remove(dhcp_handle); + }); const DHCP_TRY_ROUND: u8 = 100; for i in 0..DHCP_TRY_ROUND { diff --git a/kernel/src/net/socket/common/shutdown.rs b/kernel/src/net/socket/common/shutdown.rs index 096cb43d5..847a8a0d4 100644 --- a/kernel/src/net/socket/common/shutdown.rs +++ b/kernel/src/net/socket/common/shutdown.rs @@ -124,7 +124,7 @@ impl TryFrom for ShutdownTemp { fn try_from(value: usize) -> Result { match value { - 0 | 1 | 2 => Ok(ShutdownTemp { + 0..2 => Ok(ShutdownTemp { bit: value as u8 + 1, }), _ => Err(SystemError::EINVAL), diff --git a/kernel/src/net/socket/inet/common/mod.rs b/kernel/src/net/socket/inet/common/mod.rs index 2fa696138..455503fb3 100644 --- a/kernel/src/net/socket/inet/common/mod.rs +++ b/kernel/src/net/socket/inet/common/mod.rs @@ -53,11 +53,11 @@ impl BoundInner { }) .expect("No default interface"); - let handle = iface.sockets().lock_no_preempt().add(socket); + let handle = iface.sockets().lock_irqsave().add(socket); return Ok(Self { handle, iface }); } else { let iface = get_iface_to_bind(address).ok_or(ENODEV)?; - let handle = iface.sockets().lock_no_preempt().add(socket); + let handle = iface.sockets().lock_irqsave().add(socket); return Ok(Self { handle, iface }); } } diff --git a/kernel/src/net/socket/inet/stream/inner.rs b/kernel/src/net/socket/inet/stream/inner.rs index 241f7b3c8..0498001ac 100644 --- a/kernel/src/net/socket/inet/stream/inner.rs +++ b/kernel/src/net/socket/inet/stream/inner.rs @@ -355,6 +355,13 @@ impl Listening { .port_manager() .unbind_port(Types::Tcp, port); } + + pub fn release(&self) { + // log::debug!("Release Listening Socket"); + for inner in self.inners.iter() { + inner.release(); + } + } } #[derive(Debug)] diff --git a/kernel/src/net/socket/inet/stream/mod.rs b/kernel/src/net/socket/inet/stream/mod.rs index 3cde09250..14d13346e 100644 --- a/kernel/src/net/socket/inet/stream/mod.rs +++ b/kernel/src/net/socket/inet/stream/mod.rs @@ -348,7 +348,15 @@ impl Socket for TcpSocket { } fn close(&self) -> Result<(), SystemError> { - let inner = self.inner.write().take().unwrap(); + let Some(inner) = self.inner.write().take() else { + log::warn!("TcpSocket::close: already closed, unexpected"); + return Ok(()); + }; + if let Some(iface) = inner.iface() { + iface + .common() + .unbind_socket(self.self_ref.upgrade().unwrap()); + } match inner { // complete connecting socket close logic @@ -356,22 +364,21 @@ impl Socket for TcpSocket { 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(()) + ls.release(); } Inner::Init(init) => { init.close(); - Ok(()) } - } + }; + + Ok(()) } fn set_option(&self, level: PSOL, name: usize, val: &[u8]) -> Result<(), SystemError> {