Date: Wed, 01 Jul 2026 05:48:46 +0000 From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 0bc0b0c3f738 - main - tests/socket_afinet: extend bind_connected_port_test to cover more cases Message-ID: <6a44aa3e.1c4d6.8631dda@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=0bc0b0c3f73812fdcdb89865879c7478bcbc7323 commit 0bc0b0c3f73812fdcdb89865879c7478bcbc7323 Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2026-07-01 05:48:06 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2026-07-01 05:48:06 +0000 tests/socket_afinet: extend bind_connected_port_test to cover more cases - Test SOCK_DGRAM (UDP) sockets. - Test binding to 0:port and to a addr:port in presence of connected socket using the port. Differential Revision: https://reviews.freebsd.org/D56707 --- tests/sys/netinet/socket_afinet.c | 137 +++++++++++++++++++++++++++++--------- 1 file changed, 107 insertions(+), 30 deletions(-) diff --git a/tests/sys/netinet/socket_afinet.c b/tests/sys/netinet/socket_afinet.c index ddd4f9a6f5da..936e5ada9802 100644 --- a/tests/sys/netinet/socket_afinet.c +++ b/tests/sys/netinet/socket_afinet.c @@ -31,6 +31,7 @@ #include <sys/wait.h> #include <netinet/in.h> +#include <arpa/inet.h> #include <errno.h> #include <poll.h> @@ -516,23 +517,26 @@ ATF_TC_BODY(socket_afinet_multibind, tc) multibind_test(tc, AF_INET6, SOCK_DGRAM); } -static void -bind_connected_port_test(const atf_tc_t *tc, int domain) +/* + * Test operation of bind(2) in presence of a connected inpcb using the + * same local port. + */ +static enum bind_res +bind_connected_port_test(const atf_tc_t *tc, int domain, int type, bool wild, + bool unpriv) { struct sockaddr_in sin; struct sockaddr_in6 sin6; struct sockaddr *sinp; socklen_t slen; - int error, sd[3], tmp; + int error, ss, cs, as; enum bind_res res; /* * Create a connected socket pair. */ - sd[0] = socket(domain, SOCK_STREAM, 0); - ATF_REQUIRE_MSG(sd[0] >= 0, "socket failed: %s", strerror(errno)); - sd[1] = socket(domain, SOCK_STREAM, 0); - ATF_REQUIRE_MSG(sd[1] >= 0, "socket failed: %s", strerror(errno)); + ss = socket(domain, type, 0); + ATF_REQUIRE_MSG(ss >= 0, "socket failed: %s", strerror(errno)); if (domain == PF_INET) { memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; @@ -550,28 +554,61 @@ bind_connected_port_test(const atf_tc_t *tc, int domain) sinp = (struct sockaddr *)&sin6; } - error = bind(sd[0], sinp, sinp->sa_len); + error = bind(ss, sinp, sinp->sa_len); ATF_REQUIRE_MSG(error == 0, "bind failed: %s", strerror(errno)); - error = listen(sd[0], 1); - ATF_REQUIRE_MSG(error == 0, "listen failed: %s", strerror(errno)); - - error = getsockname(sd[0], sinp, &(socklen_t){ sinp->sa_len }); - ATF_REQUIRE_MSG(error == 0, "getsockname failed: %s", strerror(errno)); - if (domain == PF_INET) - sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - else - sin6.sin6_addr = in6addr_loopback; - error = connect(sd[1], sinp, sinp->sa_len); - ATF_REQUIRE_MSG(error == 0, "connect failed: %s", strerror(errno)); - slen = sinp->sa_len; - tmp = accept(sd[0], sinp, &slen); - ATF_REQUIRE_MSG(tmp >= 0, "accept failed: %s", strerror(errno)); - - /* bind() should succeed even from an unprivileged user. */ - res = child_bind_priv(tc, SOCK_STREAM, sinp, SO_REUSEADDR); - ATF_REQUIRE(res == BIND_REUSE_SUCCESS); - res = child_bind_unpriv(tc, SOCK_STREAM, sinp, SO_REUSEADDR); - ATF_REQUIRE(res == BIND_REUSE_SUCCESS); + + if (type == SOCK_STREAM) { + error = getsockname(ss, sinp, &(socklen_t){ sinp->sa_len }); + ATF_REQUIRE_MSG(error == 0, "getsockname failed: %s", + strerror(errno)); + error = listen(ss, 1); + ATF_REQUIRE_MSG(error == 0, + "listen failed: %s", strerror(errno)); + cs = socket(domain, type, 0); + ATF_REQUIRE_MSG(cs >= 0, "socket failed: %s", strerror(errno)); + if (domain == PF_INET) + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + else + sin6.sin6_addr = in6addr_loopback; + error = connect(cs, sinp, sinp->sa_len); + ATF_REQUIRE_MSG(error == 0, + "connect failed: %s", strerror(errno)); + slen = sinp->sa_len; + as = accept(ss, sinp, &slen); + ATF_REQUIRE_MSG(as >= 0, "accept failed: %s", strerror(errno)); + } else { + ATF_REQUIRE(type == SOCK_DGRAM); + if (domain == PF_INET) { + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sin.sin_port = htons(6666); + } else { + sin6.sin6_addr = in6addr_loopback; + sin6.sin6_port = htons(6666); + } + error = connect(ss, sinp, sinp->sa_len); + ATF_REQUIRE_MSG(error == 0, + "connect failed: %s", strerror(errno)); + error = getsockname(ss, sinp, &(socklen_t){ sinp->sa_len }); + ATF_REQUIRE_MSG(error == 0, "getsockname failed: %s", + strerror(errno)); + } + + if (wild) { + if (domain == PF_INET) + sin.sin_addr.s_addr = htonl(INADDR_ANY); + else + sin6.sin6_addr = in6addr_any; + } + + res = child_bind(tc, type, sinp, SO_REUSEADDR, unpriv); + + if (type == SOCK_STREAM) { + ATF_REQUIRE(close(as) == 0); + ATF_REQUIRE(close(cs) == 0); + } + ATF_REQUIRE(close(ss) == 0); + + return (res); } /* @@ -587,8 +624,48 @@ ATF_TC_HEAD(socket_afinet_bind_connected_port, tc) } ATF_TC_BODY(socket_afinet_bind_connected_port, tc) { - bind_connected_port_test(tc, AF_INET); - bind_connected_port_test(tc, AF_INET6); + struct socket_afinet_bind_connected_port_res { + int domain; + int type; + bool wild; + bool unpriv; + enum bind_res result; + } tests[] = { +#define x true +#define o false + /* W U */ + { AF_INET, SOCK_STREAM, x, x, BIND_REUSE_SUCCESS }, + { AF_INET, SOCK_STREAM, o, x, BIND_REUSE_SUCCESS }, + { AF_INET, SOCK_STREAM, x, o, BIND_REUSE_SUCCESS }, + { AF_INET, SOCK_STREAM, o, o, BIND_REUSE_SUCCESS }, + { AF_INET6, SOCK_STREAM, x, x, BIND_REUSE_SUCCESS }, + { AF_INET6, SOCK_STREAM, o, x, BIND_REUSE_SUCCESS }, + { AF_INET6, SOCK_STREAM, x, o, BIND_REUSE_SUCCESS }, + { AF_INET6, SOCK_STREAM, o, o, BIND_REUSE_SUCCESS }, + { AF_INET, SOCK_DGRAM, x, x, BIND_FAILED }, + { AF_INET, SOCK_DGRAM, o, x, BIND_FAILED }, + { AF_INET, SOCK_DGRAM, x, o, BIND_REUSE_SUCCESS }, + { AF_INET, SOCK_DGRAM, o, o, BIND_REUSE_SUCCESS }, + { AF_INET6, SOCK_DGRAM, x, x, BIND_FAILED }, + { AF_INET6, SOCK_DGRAM, o, x, BIND_FAILED }, + { AF_INET6, SOCK_DGRAM, x, o, BIND_REUSE_SUCCESS }, + { AF_INET6, SOCK_DGRAM, o, o, BIND_REUSE_SUCCESS }, +#undef x +#undef o + }; + + for (u_int i = 0; i < nitems(tests); i++) { + enum bind_res res; + + res = bind_connected_port_test(tc, tests[i].domain, + tests[i].type, tests[i].wild, tests[i].unpriv); + ATF_REQUIRE_MSG(res == tests[i].result, "test #%u: " + "domain %u type %u%s %sprivileged: result %u (expected %u)", + i, tests[i].domain, tests[i].type, + tests[i].wild ? " wild" : "", + tests[i].unpriv ? "un" : "", + res, tests[i].result); + } } ATF_TP_ADD_TCS(tp)home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a44aa3e.1c4d6.8631dda>
