aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2023-06-23 14:06:13 +0000
committerMark Johnston <markj@FreeBSD.org>2023-07-07 18:46:23 +0000
commitd2681db6434d1d0eb5e6d1e3af07c7b1ff9cb723 (patch)
tree6355834754e136c1145704fd9b2ec8038c89a1c8
parente27e9b3ac329b8d01c0800de32c735b2363c8862 (diff)
netinet tests: Add a test which connects a disconnected socket
MFC after: 2 weeks Sponsored by: The FreeBSD Foundation (cherry picked from commit b1c66bc44af099174afb9840c7db011a5bd0225d)
-rw-r--r--tests/sys/netinet/socket_afinet.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/tests/sys/netinet/socket_afinet.c b/tests/sys/netinet/socket_afinet.c
index 985d67d83c99..07fe90704206 100644
--- a/tests/sys/netinet/socket_afinet.c
+++ b/tests/sys/netinet/socket_afinet.c
@@ -28,9 +28,9 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <errno.h>
#include <poll.h>
#include <atf-c.h>
@@ -228,14 +228,57 @@ ATF_TC_BODY(socket_afinet_poll_rdhup, tc)
close(ss);
}
-ATF_TP_ADD_TCS(tp)
+ATF_TC_WITHOUT_HEAD(socket_afinet_stream_reconnect);
+ATF_TC_BODY(socket_afinet_stream_reconnect, tc)
{
+ struct sockaddr_in sin;
+ int ss, cs, rc;
+
+ /*
+ * Make sure that an attempt to connect(2) a connected or disconnected
+ * stream socket fails with EISCONN.
+ */
+ /* Server setup. */
+ ss = socket(PF_INET, SOCK_STREAM, 0);
+ ATF_CHECK(ss >= 0);
+ bzero(&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(sin);
+ sin.sin_port = htons(6666);
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ rc = bind(ss, (struct sockaddr *)&sin, sizeof(sin));
+ ATF_CHECK_EQ(0, rc);
+ rc = listen(ss, 1);
+ ATF_CHECK_EQ(0, rc);
+
+ /* Client connects, shuts down. */
+ cs = socket(PF_INET, SOCK_STREAM, 0);
+ ATF_CHECK(cs >= 0);
+ rc = connect(cs, (struct sockaddr *)&sin, sizeof(sin));
+ ATF_CHECK_EQ(0, rc);
+ rc = shutdown(cs, SHUT_RDWR);
+ ATF_CHECK_EQ(0, rc);
+
+ /* A subsequent connect(2) fails with EISCONN. */
+ rc = connect(cs, (struct sockaddr *)&sin, sizeof(sin));
+ ATF_CHECK_EQ(-1, rc);
+ ATF_CHECK_EQ(errno, EISCONN);
+
+ rc = close(cs);
+ ATF_CHECK_EQ(0, rc);
+ rc = close(ss);
+ ATF_CHECK_EQ(0, rc);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
ATF_TP_ADD_TC(tp, socket_afinet);
ATF_TP_ADD_TC(tp, socket_afinet_bind_zero);
ATF_TP_ADD_TC(tp, socket_afinet_bind_ok);
ATF_TP_ADD_TC(tp, socket_afinet_poll_no_rdhup);
ATF_TP_ADD_TC(tp, socket_afinet_poll_rdhup);
+ ATF_TP_ADD_TC(tp, socket_afinet_stream_reconnect);
return atf_no_error();
}