diff --git a/kernel/aster-nix/src/net/socket/unix/addr.rs b/kernel/aster-nix/src/net/socket/unix/addr.rs index c45c1f63e..5c67c767f 100644 --- a/kernel/aster-nix/src/net/socket/unix/addr.rs +++ b/kernel/aster-nix/src/net/socket/unix/addr.rs @@ -48,9 +48,17 @@ impl From for UnixSocketAddr { } } -impl From for SocketAddr { - fn from(value: UnixSocketAddrBound) -> Self { - let unix_socket_addr = UnixSocketAddr::from(value); - SocketAddr::Unix(unix_socket_addr) +impl From> for UnixSocketAddr { + fn from(value: Option) -> Self { + match value { + Some(addr) => addr.into(), + None => Self::Unnamed, + } + } +} + +impl> From for SocketAddr { + fn from(value: T) -> Self { + SocketAddr::Unix(value.into()) } } diff --git a/kernel/aster-nix/src/net/socket/unix/stream/listener.rs b/kernel/aster-nix/src/net/socket/unix/stream/listener.rs index 5d9e2ce80..08ea5d85b 100644 --- a/kernel/aster-nix/src/net/socket/unix/stream/listener.rs +++ b/kernel/aster-nix/src/net/socket/unix/stream/listener.rs @@ -6,10 +6,7 @@ use super::{connected::Connected, endpoint::Endpoint, UnixStreamSocket}; use crate::{ events::{IoEvents, Observer}, fs::{file_handle::FileLike, path::Dentry, utils::Inode}, - net::socket::{ - unix::addr::{UnixSocketAddr, UnixSocketAddrBound}, - SocketAddr, - }, + net::socket::{unix::addr::UnixSocketAddrBound, SocketAddr}, prelude::*, process::signal::{Pollee, Poller}, }; @@ -36,10 +33,7 @@ impl Listener { Connected::new(local_endpoint) }; - let peer_addr = match connected.peer_addr() { - None => SocketAddr::Unix(UnixSocketAddr::Path(String::new())), - Some(addr) => SocketAddr::from(addr.clone()), - }; + let peer_addr = connected.peer_addr().cloned().into(); let socket = UnixStreamSocket::new_connected(connected, false); diff --git a/kernel/aster-nix/src/net/socket/unix/stream/socket.rs b/kernel/aster-nix/src/net/socket/unix/stream/socket.rs index 193411400..e1e85b7ae 100644 --- a/kernel/aster-nix/src/net/socket/unix/stream/socket.rs +++ b/kernel/aster-nix/src/net/socket/unix/stream/socket.rs @@ -278,11 +278,7 @@ impl Socket for UnixStreamSocket { State::Connected(connected) => connected.addr().cloned(), }; - addr.map(Into::::into) - .ok_or(Error::with_message( - Errno::EINVAL, - "the socket does not bind to addr", - )) + Ok(addr.into()) } fn peer_addr(&self) -> Result { @@ -291,10 +287,7 @@ impl Socket for UnixStreamSocket { _ => return_errno_with_message!(Errno::ENOTCONN, "the socket is not connected"), }; - match peer_addr { - None => Ok(SocketAddr::Unix(UnixSocketAddr::Path(String::new()))), - Some(peer_addr) => Ok(SocketAddr::from(peer_addr)), - } + Ok(peer_addr.into()) } fn sendmsg( diff --git a/test/apps/network/unix_err.c b/test/apps/network/unix_err.c index 351e6b104..ac4872794 100644 --- a/test/apps/network/unix_err.c +++ b/test/apps/network/unix_err.c @@ -76,3 +76,121 @@ FN_TEST(socket_addresses) TEST_SUCC(close(sk)); } END_TEST() + +static int sk_unbound; +static int sk_bound; +static int sk_listen; +static int sk_connected; +static int sk_accepted; + +#define UNNAMED_ADDR \ + ((struct sockaddr_un){ .sun_family = AF_UNIX, .sun_path = "" }) +#define UNNAMED_ADDRLEN PATH_OFFSET + +#define BOUND_ADDR \ + ((struct sockaddr_un){ .sun_family = AF_UNIX, .sun_path = "/tmp/B0" }) +#define BOUND_ADDRLEN (PATH_OFFSET + 8) + +#define LISTEN_ADDR \ + ((struct sockaddr_un){ .sun_family = AF_UNIX, .sun_path = "/tmp/L0" }) +#define LISTEN_ADDRLEN (PATH_OFFSET + 8) + +FN_SETUP(unbound) +{ + sk_unbound = CHECK(socket(PF_UNIX, SOCK_STREAM, 0)); +} +END_SETUP() + +FN_SETUP(bound) +{ + sk_bound = CHECK(socket(PF_UNIX, SOCK_STREAM, 0)); + + CHECK(bind(sk_bound, (struct sockaddr *)&BOUND_ADDR, BOUND_ADDRLEN)); +} +END_SETUP() + +FN_SETUP(listen) +{ + sk_listen = CHECK(socket(PF_UNIX, SOCK_STREAM, 0)); + + CHECK(bind(sk_listen, (struct sockaddr *)&LISTEN_ADDR, LISTEN_ADDRLEN)); + + CHECK(listen(sk_listen, 1)); +} +END_SETUP() + +FN_SETUP(connected) +{ + sk_connected = CHECK(socket(PF_UNIX, SOCK_STREAM, 0)); + + CHECK(connect(sk_connected, (struct sockaddr *)&LISTEN_ADDR, + LISTEN_ADDRLEN)); +} +END_SETUP() + +FN_SETUP(accepted) +{ + sk_accepted = CHECK(accept(sk_listen, NULL, NULL)); +} +END_SETUP() + +FN_TEST(getsockname) +{ + struct sockaddr_un addr; + socklen_t addrlen; + + addrlen = sizeof(addr); + TEST_RES(getsockname(sk_unbound, (struct sockaddr *)&addr, &addrlen), + addrlen == UNNAMED_ADDRLEN && + memcmp(&addr, &UNNAMED_ADDR, UNNAMED_ADDRLEN) == 0); + + addrlen = sizeof(addr); + TEST_RES(getsockname(sk_bound, (struct sockaddr *)&addr, &addrlen), + addrlen == BOUND_ADDRLEN && + memcmp(&addr, &BOUND_ADDR, BOUND_ADDRLEN) == 0); + + addrlen = sizeof(addr); + TEST_RES(getsockname(sk_listen, (struct sockaddr *)&addr, &addrlen), + addrlen == LISTEN_ADDRLEN && + memcmp(&addr, &LISTEN_ADDR, LISTEN_ADDRLEN) == 0); + + addrlen = sizeof(addr); + TEST_RES(getsockname(sk_connected, (struct sockaddr *)&addr, &addrlen), + addrlen == UNNAMED_ADDRLEN && + memcmp(&addr, &UNNAMED_ADDR, UNNAMED_ADDRLEN) == 0); + + addrlen = sizeof(addr); + TEST_RES(getsockname(sk_accepted, (struct sockaddr *)&addr, &addrlen), + addrlen == LISTEN_ADDRLEN && + memcmp(&addr, &LISTEN_ADDR, LISTEN_ADDRLEN) == 0); +} +END_TEST() + +FN_TEST(getpeername) +{ + struct sockaddr_un addr; + socklen_t addrlen; + + addrlen = sizeof(addr); + TEST_ERRNO(getpeername(sk_unbound, (struct sockaddr *)&addr, &addrlen), + ENOTCONN); + + addrlen = sizeof(addr); + TEST_ERRNO(getpeername(sk_bound, (struct sockaddr *)&addr, &addrlen), + ENOTCONN); + + addrlen = sizeof(addr); + TEST_ERRNO(getpeername(sk_listen, (struct sockaddr *)&addr, &addrlen), + ENOTCONN); + + addrlen = sizeof(addr); + TEST_RES(getpeername(sk_connected, (struct sockaddr *)&addr, &addrlen), + addrlen == LISTEN_ADDRLEN && + memcmp(&addr, &LISTEN_ADDR, LISTEN_ADDRLEN) == 0); + + addrlen = sizeof(addr); + TEST_RES(getpeername(sk_accepted, (struct sockaddr *)&addr, &addrlen), + addrlen == UNNAMED_ADDRLEN && + memcmp(&addr, &UNNAMED_ADDR, UNNAMED_ADDRLEN) == 0); +} +END_TEST()