Skip to content

Commit c33082c

Browse files
authored
fix: TCP socket miss activation after close (#1085)
1 parent c4c35ed commit c33082c

File tree

6 files changed

+34
-10
lines changed

6 files changed

+34
-10
lines changed

kernel/src/driver/net/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,14 @@ impl IfaceCommon {
285285
self.bounds.write().push(socket);
286286
}
287287

288+
pub fn unbind_socket(&self, socket: Arc<dyn InetSocket>) {
289+
let mut bounds = self.bounds.write();
290+
if let Some(index) = bounds.iter().position(|s| Arc::ptr_eq(s, &socket)) {
291+
bounds.remove(index);
292+
log::debug!("unbind socket success");
293+
}
294+
}
295+
288296
// TODO: 需要在inet实现多网卡监听或路由子系统实现后移除
289297
pub fn is_default_iface(&self) -> bool {
290298
self.default_iface

kernel/src/net/net_core.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ fn dhcp_query() -> Result<(), SystemError> {
6060

6161
let sockets = || net_face.sockets().lock_irqsave();
6262

63-
// let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket);
6463
let dhcp_handle = sockets().add(dhcp_socket);
64+
defer::defer!({
65+
sockets().remove(dhcp_handle);
66+
});
6567

6668
const DHCP_TRY_ROUND: u8 = 100;
6769
for i in 0..DHCP_TRY_ROUND {

kernel/src/net/socket/common/shutdown.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl TryFrom<usize> for ShutdownTemp {
124124

125125
fn try_from(value: usize) -> Result<Self, Self::Error> {
126126
match value {
127-
0 | 1 | 2 => Ok(ShutdownTemp {
127+
0..2 => Ok(ShutdownTemp {
128128
bit: value as u8 + 1,
129129
}),
130130
_ => Err(SystemError::EINVAL),

kernel/src/net/socket/inet/common/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ impl BoundInner {
5353
})
5454
.expect("No default interface");
5555

56-
let handle = iface.sockets().lock_no_preempt().add(socket);
56+
let handle = iface.sockets().lock_irqsave().add(socket);
5757
return Ok(Self { handle, iface });
5858
} else {
5959
let iface = get_iface_to_bind(address).ok_or(ENODEV)?;
60-
let handle = iface.sockets().lock_no_preempt().add(socket);
60+
let handle = iface.sockets().lock_irqsave().add(socket);
6161
return Ok(Self { handle, iface });
6262
}
6363
}

kernel/src/net/socket/inet/stream/inner.rs

+7
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,13 @@ impl Listening {
355355
.port_manager()
356356
.unbind_port(Types::Tcp, port);
357357
}
358+
359+
pub fn release(&self) {
360+
// log::debug!("Release Listening Socket");
361+
for inner in self.inners.iter() {
362+
inner.release();
363+
}
364+
}
358365
}
359366

360367
#[derive(Debug)]

kernel/src/net/socket/inet/stream/mod.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -348,30 +348,37 @@ impl Socket for TcpSocket {
348348
}
349349

350350
fn close(&self) -> Result<(), SystemError> {
351-
let inner = self.inner.write().take().unwrap();
351+
let Some(inner) = self.inner.write().take() else {
352+
log::warn!("TcpSocket::close: already closed, unexpected");
353+
return Ok(());
354+
};
355+
if let Some(iface) = inner.iface() {
356+
iface
357+
.common()
358+
.unbind_socket(self.self_ref.upgrade().unwrap());
359+
}
352360

353361
match inner {
354362
// complete connecting socket close logic
355363
Inner::Connecting(conn) => {
356364
let conn = unsafe { conn.into_established() };
357365
conn.close();
358366
conn.release();
359-
Ok(())
360367
}
361368
Inner::Established(es) => {
362369
es.close();
363370
es.release();
364-
Ok(())
365371
}
366372
Inner::Listening(ls) => {
367373
ls.close();
368-
Ok(())
374+
ls.release();
369375
}
370376
Inner::Init(init) => {
371377
init.close();
372-
Ok(())
373378
}
374-
}
379+
};
380+
381+
Ok(())
375382
}
376383

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

0 commit comments

Comments
 (0)