Skip to content

Commit

Permalink
fix: TCP socket miss activation after close (#1085)
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuka007 authored Jan 16, 2025
1 parent c4c35ed commit c33082c
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 10 deletions.
8 changes: 8 additions & 0 deletions kernel/src/driver/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,14 @@ impl IfaceCommon {
self.bounds.write().push(socket);
}

pub fn unbind_socket(&self, socket: Arc<dyn InetSocket>) {
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
Expand Down
4 changes: 3 additions & 1 deletion kernel/src/net/net_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/net/socket/common/shutdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ impl TryFrom<usize> for ShutdownTemp {

fn try_from(value: usize) -> Result<Self, Self::Error> {
match value {
0 | 1 | 2 => Ok(ShutdownTemp {
0..2 => Ok(ShutdownTemp {
bit: value as u8 + 1,
}),
_ => Err(SystemError::EINVAL),
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/net/socket/inet/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
}
}
Expand Down
7 changes: 7 additions & 0 deletions kernel/src/net/socket/inet/stream/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
19 changes: 13 additions & 6 deletions kernel/src/net/socket/inet/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,30 +348,37 @@ 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
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(())
ls.release();
}
Inner::Init(init) => {
init.close();
Ok(())
}
}
};

Ok(())
}

fn set_option(&self, level: PSOL, name: usize, val: &[u8]) -> Result<(), SystemError> {
Expand Down

0 comments on commit c33082c

Please sign in to comment.