mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-18 20:16:42 +00:00
Fix race conditions in UNIX socket listen()
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
a2d94675eb
commit
ac19a7e0e7
@ -16,9 +16,9 @@ pub(super) struct Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Listener {
|
impl Listener {
|
||||||
pub(super) fn new(addr: UnixSocketAddrBound, backlog: usize) -> Result<Self> {
|
pub(super) fn new(addr: UnixSocketAddrBound, backlog: usize) -> Self {
|
||||||
let backlog = BACKLOG_TABLE.add_backlog(addr, backlog)?;
|
let backlog = BACKLOG_TABLE.add_backlog(addr, backlog).unwrap();
|
||||||
Ok(Self { backlog })
|
Self { backlog }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn addr(&self) -> &UnixSocketAddrBound {
|
pub(super) fn addr(&self) -> &UnixSocketAddrBound {
|
||||||
@ -78,21 +78,22 @@ impl BacklogTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_backlog(&self, addr: UnixSocketAddrBound, backlog: usize) -> Result<Arc<Backlog>> {
|
fn add_backlog(&self, addr: UnixSocketAddrBound, backlog: usize) -> Option<Arc<Backlog>> {
|
||||||
let inode = {
|
let inode = {
|
||||||
let UnixSocketAddrBound::Path(_, ref dentry) = addr else {
|
let UnixSocketAddrBound::Path(_, ref dentry) = addr else {
|
||||||
todo!()
|
todo!()
|
||||||
};
|
};
|
||||||
create_keyable_inode(dentry)
|
create_keyable_inode(dentry)
|
||||||
};
|
};
|
||||||
|
let new_backlog = Arc::new(Backlog::new(addr, backlog));
|
||||||
|
|
||||||
let mut backlog_sockets = self.backlog_sockets.write();
|
let mut backlog_sockets = self.backlog_sockets.write();
|
||||||
if backlog_sockets.contains_key(&inode) {
|
if backlog_sockets.contains_key(&inode) {
|
||||||
return_errno_with_message!(Errno::EADDRINUSE, "the addr is already used");
|
return None;
|
||||||
}
|
}
|
||||||
let new_backlog = Arc::new(Backlog::new(addr, backlog));
|
|
||||||
backlog_sockets.insert(inode, new_backlog.clone());
|
backlog_sockets.insert(inode, new_backlog.clone());
|
||||||
Ok(new_backlog)
|
|
||||||
|
Some(new_backlog)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_backlog(&self, addr: &UnixSocketAddrBound) -> Result<Arc<Backlog>> {
|
fn get_backlog(&self, addr: &UnixSocketAddrBound) -> Result<Arc<Backlog>> {
|
||||||
|
@ -232,7 +232,9 @@ impl Socket for UnixStreamSocket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn listen(&self, backlog: usize) -> Result<()> {
|
fn listen(&self, backlog: usize) -> Result<()> {
|
||||||
let addr = match &*self.state.read() {
|
let mut state = self.state.write();
|
||||||
|
|
||||||
|
let addr = match &*state {
|
||||||
State::Init(init) => init
|
State::Init(init) => init
|
||||||
.addr()
|
.addr()
|
||||||
.ok_or(Error::with_message(
|
.ok_or(Error::with_message(
|
||||||
@ -248,8 +250,9 @@ impl Socket for UnixStreamSocket {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let listener = Listener::new(addr, backlog)?;
|
let listener = Listener::new(addr, backlog);
|
||||||
*self.state.write() = State::Listen(listener);
|
*state = State::Listen(listener);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user