Remove unnecessary self-connecting check

This commit is contained in:
Ruihan Li 2024-07-26 22:47:42 +08:00 committed by Tate, Hongliang Tian
parent 8bcb5a2a5f
commit 6b50d28ba1
4 changed files with 40 additions and 21 deletions

View File

@ -9,22 +9,12 @@ pub enum UnixSocketAddr {
Abstract(Vec<u8>),
}
#[derive(Clone)]
#[derive(Clone, Debug)]
pub(super) enum UnixSocketAddrBound {
Path(Arc<Dentry>),
Abstract(Vec<u8>),
}
impl PartialEq for UnixSocketAddrBound {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Abstract(l0), Self::Abstract(r0)) => l0 == r0,
(Self::Path(l0), Self::Path(r0)) => Arc::ptr_eq(l0.inode(), r0.inode()),
_ => false,
}
}
}
impl TryFrom<SocketAddr> for UnixSocketAddr {
type Error = Error;

View File

@ -45,17 +45,11 @@ impl Init {
}
pub(super) fn connect(&self, remote_addr: &UnixSocketAddrBound) -> Result<Connected> {
let addr = self.addr();
if let Some(addr) = addr {
if *addr == *remote_addr {
return_errno_with_message!(Errno::EINVAL, "try to connect to self is invalid");
}
}
let (this_end, remote_end) = Endpoint::new_pair(addr.cloned(), Some(remote_addr.clone()));
let (this_end, remote_end) =
Endpoint::new_pair(self.addr.clone(), Some(remote_addr.clone()));
push_incoming(remote_addr, remote_end)?;
Ok(Connected::new(this_end))
}

View File

@ -222,9 +222,20 @@ impl Socket for UnixStreamSocket {
}
};
// Note that the Linux kernel implementation locks the remote socket and checks to see if
// it is listening first. This is different from our implementation, which locks the local
// socket and checks the state of the local socket first.
//
// The difference may result in different error codes, but it's doubtful that this will
// ever lead to real problems.
//
// See also <https://elixir.bootlin.com/linux/v6.10.4/source/net/unix/af_unix.c#L1527>.
let connected = match &*self.state.read() {
State::Init(init) => init.connect(&remote_addr)?,
State::Listen(_) => return_errno_with_message!(Errno::EINVAL, "the socket is listened"),
State::Listen(_) => {
return_errno_with_message!(Errno::EINVAL, "the socket is listening")
}
State::Connected(_) => {
return_errno_with_message!(Errno::EISCONN, "the socket is connected")
}

View File

@ -194,3 +194,27 @@ FN_TEST(getpeername)
memcmp(&addr, &UNNAMED_ADDR, UNNAMED_ADDRLEN) == 0);
}
END_TEST()
FN_TEST(connect)
{
TEST_ERRNO(connect(sk_unbound, (struct sockaddr *)&BOUND_ADDR,
BOUND_ADDRLEN),
ECONNREFUSED);
TEST_ERRNO(connect(sk_bound, (struct sockaddr *)&BOUND_ADDR,
BOUND_ADDRLEN),
ECONNREFUSED);
TEST_ERRNO(connect(sk_listen, (struct sockaddr *)&LISTEN_ADDR,
LISTEN_ADDRLEN),
EINVAL);
TEST_ERRNO(connect(sk_connected, (struct sockaddr *)&LISTEN_ADDR,
LISTEN_ADDRLEN),
EISCONN);
TEST_ERRNO(connect(sk_connected, (struct sockaddr *)&LISTEN_ADDR,
LISTEN_ADDRLEN),
EISCONN);
}
END_TEST()