diff --git a/kernel/src/net/socket/ip/datagram/bound.rs b/kernel/src/net/socket/ip/datagram/bound.rs index 9eb825d01..831444667 100644 --- a/kernel/src/net/socket/ip/datagram/bound.rs +++ b/kernel/src/net/socket/ip/datagram/bound.rs @@ -8,7 +8,7 @@ use aster_bigtcp::{ use crate::{ events::IoEvents, net::{ - iface::{Iface, UdpSocket}, + iface::{BoundPort, Iface, UdpSocket}, socket::util::{datagram_common, SendRecvFlags}, }, prelude::*, @@ -31,6 +31,10 @@ impl BoundDatagram { pub(super) fn iface(&self) -> &Arc { self.bound_socket.iface() } + + pub(super) fn bound_port(&self) -> &BoundPort { + self.bound_socket.bound_port() + } } impl datagram_common::Bound for BoundDatagram { diff --git a/kernel/src/net/socket/ip/datagram/mod.rs b/kernel/src/net/socket/ip/datagram/mod.rs index b88dfea86..460834563 100644 --- a/kernel/src/net/socket/ip/datagram/mod.rs +++ b/kernel/src/net/socket/ip/datagram/mod.rs @@ -260,4 +260,12 @@ impl GetSocketLevelOption for Inner { } } -impl SetSocketLevelOption for Inner {} +impl SetSocketLevelOption for Inner { + fn set_reuse_addr(&self, reuse_addr: bool) { + let Inner::Bound(bound) = self else { + return; + }; + + bound.bound_port().set_can_reuse(reuse_addr); + } +} diff --git a/test/src/apps/network/udp_err.c b/test/src/apps/network/udp_err.c index 83450e881..ec67645ca 100644 --- a/test/src/apps/network/udp_err.c +++ b/test/src/apps/network/udp_err.c @@ -184,14 +184,11 @@ FN_TEST(bind_reuseaddr) TEST_ERRNO(bind(sk2, psaddr, addrlen), EADDRINUSE); - // FIXME: The test will fail in Asterinas since it doesn't check - // if the previous socket was bound with `SO_REUSEADDR` - // - // TEST_SUCC(setsockopt(sk1, SOL_SOCKET, SO_REUSEADDR, &disable, - // sizeof(disable))); - // TEST_SUCC(setsockopt(sk2, SOL_SOCKET, SO_REUSEADDR, &enable, - // sizeof(enable))); - // TEST_ERRNO(bind(sk2, psaddr, addrlen), EADDRINUSE); + TEST_SUCC(setsockopt(sk1, SOL_SOCKET, SO_REUSEADDR, &disable, + sizeof(disable))); + TEST_SUCC(setsockopt(sk2, SOL_SOCKET, SO_REUSEADDR, &enable, + sizeof(enable))); + TEST_ERRNO(bind(sk2, psaddr, addrlen), EADDRINUSE); TEST_SUCC(setsockopt(sk1, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))); @@ -199,6 +196,12 @@ FN_TEST(bind_reuseaddr) sizeof(disable))); TEST_ERRNO(bind(sk2, psaddr, addrlen), EADDRINUSE); + TEST_SUCC(setsockopt(sk1, SOL_SOCKET, SO_REUSEADDR, &disable, + sizeof(disable))); + TEST_SUCC(setsockopt(sk2, SOL_SOCKET, SO_REUSEADDR, &enable, + sizeof(enable))); + TEST_ERRNO(bind(sk2, psaddr, addrlen), EADDRINUSE); + TEST_SUCC(setsockopt(sk1, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable))); TEST_SUCC(setsockopt(sk2, SOL_SOCKET, SO_REUSEADDR, &enable,