1a8eb96d5SAlan Somers /*- 2eb338e23SGleb Smirnoff * 3eb338e23SGleb Smirnoff * Copyright (c) 2024 Gleb Smirnoff <glebius@FreeBSD.org> 4a8eb96d5SAlan Somers * Copyright (c) 2014 Spectra Logic Corporation. All rights reserved. 5eb338e23SGleb Smirnoff * 6a8eb96d5SAlan Somers * Redistribution and use in source and binary forms, with or without 7a8eb96d5SAlan Somers * modification, are permitted provided that the following conditions 8a8eb96d5SAlan Somers * are met: 9a8eb96d5SAlan Somers * 1. Redistributions of source code must retain the above copyright 10a8eb96d5SAlan Somers * notice, this list of conditions and the following disclaimer. 11a8eb96d5SAlan Somers * 2. Redistributions in binary form must reproduce the above copyright 12a8eb96d5SAlan Somers * notice, this list of conditions and the following disclaimer in the 13a8eb96d5SAlan Somers * documentation and/or other materials provided with the distribution. 14a8eb96d5SAlan Somers * 15a8eb96d5SAlan Somers * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16a8eb96d5SAlan Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17a8eb96d5SAlan Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18a8eb96d5SAlan Somers * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 19a8eb96d5SAlan Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20a8eb96d5SAlan Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21a8eb96d5SAlan Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22a8eb96d5SAlan Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23a8eb96d5SAlan Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24a8eb96d5SAlan Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25a8eb96d5SAlan Somers * SUCH DAMAGE. 26a8eb96d5SAlan Somers */ 27a8eb96d5SAlan Somers 28a8eb96d5SAlan Somers #include <sys/cdefs.h> 29a8eb96d5SAlan Somers #include <errno.h> 30a8eb96d5SAlan Somers #include <fcntl.h> 31a8eb96d5SAlan Somers #include <pthread.h> 32a8eb96d5SAlan Somers #include <signal.h> 33eb338e23SGleb Smirnoff #include <stdlib.h> 34a8eb96d5SAlan Somers #include <sys/socket.h> 35eb338e23SGleb Smirnoff #include <sys/sysctl.h> 36a8eb96d5SAlan Somers #include <sys/un.h> 37a8eb96d5SAlan Somers 38a8eb96d5SAlan Somers #include <stdio.h> 39a8eb96d5SAlan Somers 40a8eb96d5SAlan Somers #include <atf-c.h> 41a8eb96d5SAlan Somers 42a8eb96d5SAlan Somers /* 43a8eb96d5SAlan Somers * Helper functions 44a8eb96d5SAlan Somers */ 45a8eb96d5SAlan Somers 46a8eb96d5SAlan Somers #define MIN(x, y) ((x) < (y) ? (x) : (y)) 47a8eb96d5SAlan Somers #define MAX(x, y) ((x) > (y) ? (x) : (y)) 48a8eb96d5SAlan Somers 495d5b721aSAlan Somers static void 50a8eb96d5SAlan Somers do_socketpair(int *sv) 51a8eb96d5SAlan Somers { 52a8eb96d5SAlan Somers int s; 53a8eb96d5SAlan Somers 54a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 55a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 56a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] >= 0); 57a8eb96d5SAlan Somers ATF_REQUIRE(sv[1] >= 0); 58a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] != sv[1]); 59a8eb96d5SAlan Somers } 60a8eb96d5SAlan Somers 615d5b721aSAlan Somers static void 62a8eb96d5SAlan Somers do_socketpair_nonblocking(int *sv) 63a8eb96d5SAlan Somers { 64a8eb96d5SAlan Somers int s; 65a8eb96d5SAlan Somers 66a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 67a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 68a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] >= 0); 69a8eb96d5SAlan Somers ATF_REQUIRE(sv[1] >= 0); 70a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] != sv[1]); 71a8eb96d5SAlan Somers ATF_REQUIRE(-1 != fcntl(sv[0], F_SETFL, O_NONBLOCK)); 72a8eb96d5SAlan Somers ATF_REQUIRE(-1 != fcntl(sv[1], F_SETFL, O_NONBLOCK)); 73a8eb96d5SAlan Somers } 74a8eb96d5SAlan Somers 75a8eb96d5SAlan Somers /* 761f46c32cSGleb Smirnoff * Returns a bound and listening socket. 77a8eb96d5SAlan Somers * @return const char* The path to the socket 78a8eb96d5SAlan Somers */ 791f46c32cSGleb Smirnoff static const struct sockaddr_un * 801f46c32cSGleb Smirnoff mk_listening_socket(int *sv) 81a8eb96d5SAlan Somers { 82a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 831f46c32cSGleb Smirnoff static const struct sockaddr_un sun = { 841f46c32cSGleb Smirnoff .sun_family = AF_LOCAL, 851f46c32cSGleb Smirnoff .sun_len = sizeof(sun), 861f46c32cSGleb Smirnoff .sun_path = "sock", 871f46c32cSGleb Smirnoff }; 881f46c32cSGleb Smirnoff int s, r, l; 89a8eb96d5SAlan Somers 90a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 91a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 92a8eb96d5SAlan Somers 931f46c32cSGleb Smirnoff r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 941f46c32cSGleb Smirnoff l = listen(s, -1); 951f46c32cSGleb Smirnoff ATF_CHECK_EQ(0, r); 961f46c32cSGleb Smirnoff ATF_CHECK_EQ(0, l); 971f46c32cSGleb Smirnoff 981f46c32cSGleb Smirnoff if (sv != NULL) 991f46c32cSGleb Smirnoff *sv = s; 1001f46c32cSGleb Smirnoff 1011f46c32cSGleb Smirnoff return (&sun); 1021f46c32cSGleb Smirnoff } 1031f46c32cSGleb Smirnoff 1041f46c32cSGleb Smirnoff /* 1051f46c32cSGleb Smirnoff * Returns a pair of sockets made the hard way: bind, listen, connect & accept 1061f46c32cSGleb Smirnoff * @return const char* The path to the socket 1071f46c32cSGleb Smirnoff */ 1081f46c32cSGleb Smirnoff static const struct sockaddr_un * 1091f46c32cSGleb Smirnoff mk_pair_of_sockets(int *sv) 1101f46c32cSGleb Smirnoff { 1111f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 1121f46c32cSGleb Smirnoff int s, s2, err, s1; 1131f46c32cSGleb Smirnoff 1141f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 115a8eb96d5SAlan Somers 116a8eb96d5SAlan Somers /* Create the other socket */ 117a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 118a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 1191f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 120a8eb96d5SAlan Somers if (err != 0) { 121a8eb96d5SAlan Somers perror("connect"); 122a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 123a8eb96d5SAlan Somers } 124a8eb96d5SAlan Somers 125a8eb96d5SAlan Somers /* Accept it */ 126a8eb96d5SAlan Somers s1 = accept(s, NULL, NULL); 127a8eb96d5SAlan Somers if (s1 == -1) { 128a8eb96d5SAlan Somers perror("accept"); 129a8eb96d5SAlan Somers atf_tc_fail("accept(2) failed"); 130a8eb96d5SAlan Somers } 131a8eb96d5SAlan Somers 132a8eb96d5SAlan Somers sv[0] = s1; 133a8eb96d5SAlan Somers sv[1] = s2; 134e594026dSAlan Somers 135e594026dSAlan Somers close(s); 136e594026dSAlan Somers 1371f46c32cSGleb Smirnoff return (sun); 138a8eb96d5SAlan Somers } 139a8eb96d5SAlan Somers 140a8eb96d5SAlan Somers static volatile sig_atomic_t got_sigpipe = 0; 141a8eb96d5SAlan Somers static void 1425d5b721aSAlan Somers shutdown_send_sigpipe_handler(int __unused x) 143a8eb96d5SAlan Somers { 144a8eb96d5SAlan Somers got_sigpipe = 1; 145a8eb96d5SAlan Somers } 146a8eb96d5SAlan Somers 147a8eb96d5SAlan Somers /* 148a8eb96d5SAlan Somers * Parameterized test function bodies 149a8eb96d5SAlan Somers */ 1505d5b721aSAlan Somers static void 151ea703329SBrooks Davis test_eagain(int sndbufsize, int rcvbufsize) 152a8eb96d5SAlan Somers { 153a8eb96d5SAlan Somers int i; 154a8eb96d5SAlan Somers int sv[2]; 155a8eb96d5SAlan Somers const size_t totalsize = (sndbufsize + rcvbufsize) * 2; 156a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 1575d5b721aSAlan Somers const int numpkts = totalsize / pktsize; 158a8eb96d5SAlan Somers char sndbuf[pktsize]; 1595d5b721aSAlan Somers ssize_t ssize; 160a8eb96d5SAlan Somers 161a8eb96d5SAlan Somers /* setup the socket pair */ 162b9a9db10SAlan Somers do_socketpair_nonblocking(sv); 163a8eb96d5SAlan Somers /* Setup the buffers */ 164a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 165a8eb96d5SAlan Somers sizeof(sndbufsize))); 166a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 167a8eb96d5SAlan Somers sizeof(rcvbufsize))); 168a8eb96d5SAlan Somers 169a8eb96d5SAlan Somers bzero(sndbuf, pktsize); 170a8eb96d5SAlan Somers /* Send data until we get EAGAIN */ 1715d5b721aSAlan Somers for(i=0; i < numpkts; i++) { 172a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 173a8eb96d5SAlan Somers if (ssize == -1) { 174e594026dSAlan Somers if (errno == EAGAIN) { 175e594026dSAlan Somers close(sv[0]); 176e594026dSAlan Somers close(sv[1]); 177a8eb96d5SAlan Somers atf_tc_pass(); 178e594026dSAlan Somers } 179a8eb96d5SAlan Somers else { 180a8eb96d5SAlan Somers perror("send"); 181a8eb96d5SAlan Somers atf_tc_fail("send returned < 0 but not EAGAIN"); 182a8eb96d5SAlan Somers } 183a8eb96d5SAlan Somers } 184a8eb96d5SAlan Somers } 185a8eb96d5SAlan Somers atf_tc_fail("Never got EAGAIN"); 186a8eb96d5SAlan Somers } 187a8eb96d5SAlan Somers 1885d5b721aSAlan Somers static void 189ea703329SBrooks Davis test_sendrecv_symmetric_buffers(int bufsize, int blocking) { 190a8eb96d5SAlan Somers int s; 191a8eb96d5SAlan Somers int sv[2]; 1925d5b721aSAlan Somers const ssize_t pktsize = bufsize / 2; 193a8eb96d5SAlan Somers char sndbuf[pktsize]; 194a8eb96d5SAlan Somers char recv_buf[pktsize]; 195a8eb96d5SAlan Somers ssize_t ssize, rsize; 196a8eb96d5SAlan Somers 197a8eb96d5SAlan Somers /* setup the socket pair */ 198a8eb96d5SAlan Somers if (blocking) 199a8eb96d5SAlan Somers do_socketpair(sv); 200a8eb96d5SAlan Somers else 201a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 202a8eb96d5SAlan Somers 203a8eb96d5SAlan Somers /* Setup the buffers */ 204a8eb96d5SAlan Somers s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); 205a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 206a8eb96d5SAlan Somers s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); 207a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 208a8eb96d5SAlan Somers 209a8eb96d5SAlan Somers /* Fill the send buffer */ 210a8eb96d5SAlan Somers bzero(sndbuf, pktsize); 211a8eb96d5SAlan Somers 212a8eb96d5SAlan Somers /* send and receive the packet */ 213a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 214a8eb96d5SAlan Somers if (ssize < 0) { 215a8eb96d5SAlan Somers perror("send"); 216a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 217a8eb96d5SAlan Somers } 218a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd", 219a8eb96d5SAlan Somers pktsize, ssize); 220a8eb96d5SAlan Somers 221a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 222a8eb96d5SAlan Somers if (rsize < 0) { 223a8eb96d5SAlan Somers perror("recv"); 224a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 225a8eb96d5SAlan Somers } 226a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd", 227a8eb96d5SAlan Somers pktsize, rsize); 228e594026dSAlan Somers close(sv[0]); 229e594026dSAlan Somers close(sv[1]); 230a8eb96d5SAlan Somers } 231a8eb96d5SAlan Somers 2325d5b721aSAlan Somers static void 233ea703329SBrooks Davis test_pipe_simulator(int sndbufsize, int rcvbufsize) 234a8eb96d5SAlan Somers { 2355d5b721aSAlan Somers int num_sent, num_received; 236a8eb96d5SAlan Somers int sv[2]; 2375d5b721aSAlan Somers const ssize_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 238a8eb96d5SAlan Somers int numpkts; 239a8eb96d5SAlan Somers char sndbuf[pktsize]; 240a8eb96d5SAlan Somers char rcvbuf[pktsize]; 241a8eb96d5SAlan Somers char comparebuf[pktsize]; 242a8eb96d5SAlan Somers ssize_t ssize, rsize; 243a8eb96d5SAlan Somers bool currently_sending = true; 244a8eb96d5SAlan Somers 245a8eb96d5SAlan Somers /* setup the socket pair */ 246a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 247a8eb96d5SAlan Somers /* Setup the buffers */ 248a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 249a8eb96d5SAlan Somers sizeof(sndbufsize))); 250a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 251a8eb96d5SAlan Somers sizeof(rcvbufsize))); 252a8eb96d5SAlan Somers 253a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 254a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 255a8eb96d5SAlan Somers for (num_sent=0, num_received=0; 256a8eb96d5SAlan Somers num_sent < numpkts || num_received < numpkts; ) { 257a8eb96d5SAlan Somers if (currently_sending && num_sent < numpkts) { 258a8eb96d5SAlan Somers /* The simulated sending process */ 259a8eb96d5SAlan Somers /* fill the buffer */ 260a8eb96d5SAlan Somers memset(sndbuf, num_sent, pktsize); 261a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 262a8eb96d5SAlan Somers if (ssize < 0) { 263a8eb96d5SAlan Somers /* 264a8eb96d5SAlan Somers * XXX: This is bug-compatible with the kernel. 265a8eb96d5SAlan Somers * The kernel returns EMSGSIZE when it should 266a8eb96d5SAlan Somers * return EAGAIN 267a8eb96d5SAlan Somers */ 268a8eb96d5SAlan Somers if (errno == EAGAIN || errno == EMSGSIZE) 269a8eb96d5SAlan Somers currently_sending = false; 270a8eb96d5SAlan Somers else { 271a8eb96d5SAlan Somers perror("send"); 272a8eb96d5SAlan Somers atf_tc_fail("send failed"); 273a8eb96d5SAlan Somers } 274a8eb96d5SAlan Somers } else { 275a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 276a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 277a8eb96d5SAlan Somers pktsize, ssize); 278a8eb96d5SAlan Somers num_sent++; 279a8eb96d5SAlan Somers } 280a8eb96d5SAlan Somers } else { 281a8eb96d5SAlan Somers /* The simulated receiving process */ 282a8eb96d5SAlan Somers rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL); 283a8eb96d5SAlan Somers if (rsize < 0) { 284a8eb96d5SAlan Somers if (errno == EAGAIN) { 285a8eb96d5SAlan Somers currently_sending = true; 286a8eb96d5SAlan Somers ATF_REQUIRE_MSG(num_sent < numpkts, 287a8eb96d5SAlan Somers "Packets were lost!"); 288a8eb96d5SAlan Somers } 289a8eb96d5SAlan Somers else { 290a8eb96d5SAlan Somers perror("recv"); 291a8eb96d5SAlan Somers atf_tc_fail("recv failed"); 292a8eb96d5SAlan Somers } 293a8eb96d5SAlan Somers } else { 294a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 295a8eb96d5SAlan Somers "expected %zd=recv(...) but got %zd", 296a8eb96d5SAlan Somers pktsize, rsize); 297a8eb96d5SAlan Somers memset(comparebuf, num_received, pktsize); 298a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf, 299a8eb96d5SAlan Somers pktsize), 300a8eb96d5SAlan Somers "Received data miscompare"); 301a8eb96d5SAlan Somers num_received++; 302a8eb96d5SAlan Somers } 303a8eb96d5SAlan Somers } 304a8eb96d5SAlan Somers } 305e594026dSAlan Somers close(sv[0]); 306e594026dSAlan Somers close(sv[1]); 307a8eb96d5SAlan Somers } 308a8eb96d5SAlan Somers 309a8eb96d5SAlan Somers typedef struct { 310a8eb96d5SAlan Somers ssize_t pktsize; 311a8eb96d5SAlan Somers int numpkts; 312a8eb96d5SAlan Somers int so; 313a8eb96d5SAlan Somers } test_pipe_thread_data_t; 314a8eb96d5SAlan Somers 315a8eb96d5SAlan Somers static void* 316a8eb96d5SAlan Somers test_pipe_writer(void* args) 317a8eb96d5SAlan Somers { 318a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 319a8eb96d5SAlan Somers char sndbuf[td->pktsize]; 320a8eb96d5SAlan Somers ssize_t ssize; 321a8eb96d5SAlan Somers int i; 322a8eb96d5SAlan Somers 323a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 324a8eb96d5SAlan Somers memset(sndbuf, i, td->pktsize); 325a8eb96d5SAlan Somers ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR); 326a8eb96d5SAlan Somers if (ssize < 0) { 327a8eb96d5SAlan Somers perror("send"); 328a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 329a8eb96d5SAlan Somers } 330a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, ssize, 331a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 332a8eb96d5SAlan Somers td->pktsize, ssize); 333a8eb96d5SAlan Somers } 334a8eb96d5SAlan Somers return (0); 335a8eb96d5SAlan Somers } 336a8eb96d5SAlan Somers 337a8eb96d5SAlan Somers static void* 338a8eb96d5SAlan Somers test_pipe_reader(void* args) 339a8eb96d5SAlan Somers { 340a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 341a8eb96d5SAlan Somers char rcvbuf[td->pktsize]; 342a8eb96d5SAlan Somers char comparebuf[td->pktsize]; 343a8eb96d5SAlan Somers ssize_t rsize; 344a8eb96d5SAlan Somers int i, d; 345a8eb96d5SAlan Somers 346a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 347a8eb96d5SAlan Somers memset(comparebuf, i, td->pktsize); 348a8eb96d5SAlan Somers rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL); 349a8eb96d5SAlan Somers if (rsize < 0) { 350a8eb96d5SAlan Somers perror("recv"); 351a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 352a8eb96d5SAlan Somers } 353a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, rsize, 354a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 355a8eb96d5SAlan Somers td->pktsize, rsize); 356a8eb96d5SAlan Somers d = memcmp(comparebuf, rcvbuf, td->pktsize); 357a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, d, 358a8eb96d5SAlan Somers "Received data miscompare on packet %d", i); 359a8eb96d5SAlan Somers } 360a8eb96d5SAlan Somers return (0); 361a8eb96d5SAlan Somers } 362a8eb96d5SAlan Somers 363a8eb96d5SAlan Somers 3645d5b721aSAlan Somers static void 365ea703329SBrooks Davis test_pipe(int sndbufsize, int rcvbufsize) 366a8eb96d5SAlan Somers { 367a8eb96d5SAlan Somers test_pipe_thread_data_t writer_data, reader_data; 368a8eb96d5SAlan Somers pthread_t writer, reader; 369a8eb96d5SAlan Somers int sv[2]; 370a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 371a8eb96d5SAlan Somers int numpkts; 372a8eb96d5SAlan Somers 373a8eb96d5SAlan Somers /* setup the socket pair */ 374a8eb96d5SAlan Somers do_socketpair(sv); 375a8eb96d5SAlan Somers /* Setup the buffers */ 376a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 377a8eb96d5SAlan Somers sizeof(sndbufsize))); 378a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 379a8eb96d5SAlan Somers sizeof(rcvbufsize))); 380a8eb96d5SAlan Somers 381a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 382a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 383a8eb96d5SAlan Somers 384a8eb96d5SAlan Somers /* Start the child threads */ 385a8eb96d5SAlan Somers writer_data.pktsize = pktsize; 386a8eb96d5SAlan Somers writer_data.numpkts = numpkts; 387a8eb96d5SAlan Somers writer_data.so = sv[0]; 388a8eb96d5SAlan Somers reader_data.pktsize = pktsize; 389a8eb96d5SAlan Somers reader_data.numpkts = numpkts; 390a8eb96d5SAlan Somers reader_data.so = sv[1]; 391a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer, 392a8eb96d5SAlan Somers (void*)&writer_data)); 3938de34a88SAlan Somers /* 3948de34a88SAlan Somers * Give the writer time to start writing, and hopefully block, before 3958de34a88SAlan Somers * starting the reader. This increases the likelihood of the test case 3968de34a88SAlan Somers * failing due to PR kern/185812 3978de34a88SAlan Somers */ 3988de34a88SAlan Somers usleep(1000); 399a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader, 400a8eb96d5SAlan Somers (void*)&reader_data)); 401a8eb96d5SAlan Somers 402a8eb96d5SAlan Somers /* Join the children */ 403a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(writer, NULL)); 404a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(reader, NULL)); 405e594026dSAlan Somers close(sv[0]); 406e594026dSAlan Somers close(sv[1]); 407a8eb96d5SAlan Somers } 408a8eb96d5SAlan Somers 409a8eb96d5SAlan Somers 410a8eb96d5SAlan Somers /* 411a8eb96d5SAlan Somers * Test Cases 412a8eb96d5SAlan Somers */ 413a8eb96d5SAlan Somers 414a8eb96d5SAlan Somers /* Create a SEQPACKET socket */ 415a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socket); 416a8eb96d5SAlan Somers ATF_TC_BODY(create_socket, tc) 417a8eb96d5SAlan Somers { 418a8eb96d5SAlan Somers int s; 419a8eb96d5SAlan Somers 420a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 4216addc01eSAlan Somers ATF_REQUIRE(s >= 0); 422e594026dSAlan Somers close(s); 423a8eb96d5SAlan Somers } 424a8eb96d5SAlan Somers 425a8eb96d5SAlan Somers /* Create SEQPACKET sockets using socketpair(2) */ 426a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socketpair); 427a8eb96d5SAlan Somers ATF_TC_BODY(create_socketpair, tc) 428a8eb96d5SAlan Somers { 429a8eb96d5SAlan Somers int sv[2]; 430a8eb96d5SAlan Somers int s; 431a8eb96d5SAlan Somers 432a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 433a8eb96d5SAlan Somers ATF_CHECK_EQ(0, s); 434a8eb96d5SAlan Somers ATF_CHECK(sv[0] >= 0); 435a8eb96d5SAlan Somers ATF_CHECK(sv[1] >= 0); 436a8eb96d5SAlan Somers ATF_CHECK(sv[0] != sv[1]); 437e594026dSAlan Somers close(sv[0]); 438e594026dSAlan Somers close(sv[1]); 439a8eb96d5SAlan Somers } 440a8eb96d5SAlan Somers 441a8eb96d5SAlan Somers /* Call listen(2) without first calling bind(2). It should fail */ 442a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_unbound); 443a8eb96d5SAlan Somers ATF_TC_BODY(listen_unbound, tc) 444a8eb96d5SAlan Somers { 445a8eb96d5SAlan Somers int s, r; 446a8eb96d5SAlan Somers 447a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 448a8eb96d5SAlan Somers ATF_REQUIRE(s > 0); 449a8eb96d5SAlan Somers r = listen(s, -1); 450a8eb96d5SAlan Somers /* expect listen to fail since we haven't called bind(2) */ 451a8eb96d5SAlan Somers ATF_CHECK(r != 0); 452e594026dSAlan Somers close(s); 453a8eb96d5SAlan Somers } 454a8eb96d5SAlan Somers 455a8eb96d5SAlan Somers /* Bind the socket to a file */ 456a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(bind); 457a8eb96d5SAlan Somers ATF_TC_BODY(bind, tc) 458a8eb96d5SAlan Somers { 459a8eb96d5SAlan Somers struct sockaddr_un sun; 460a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 461a8eb96d5SAlan Somers const char *path = "sock"; 462a8eb96d5SAlan Somers int s, r; 463a8eb96d5SAlan Somers 464a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 465a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 466a8eb96d5SAlan Somers 467a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 468a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 469a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 470a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 471a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 472a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 473e594026dSAlan Somers close(s); 474a8eb96d5SAlan Somers } 475a8eb96d5SAlan Somers 476a8eb96d5SAlan Somers /* listen(2) a socket that is already bound(2) should succeed */ 477a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_bound); 478a8eb96d5SAlan Somers ATF_TC_BODY(listen_bound, tc) 479a8eb96d5SAlan Somers { 4801f46c32cSGleb Smirnoff int s; 481a8eb96d5SAlan Somers 4821f46c32cSGleb Smirnoff (void)mk_listening_socket(&s); 483e594026dSAlan Somers close(s); 484a8eb96d5SAlan Somers } 485a8eb96d5SAlan Somers 486a8eb96d5SAlan Somers /* connect(2) can make a connection */ 487a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(connect); 488a8eb96d5SAlan Somers ATF_TC_BODY(connect, tc) 489a8eb96d5SAlan Somers { 4901f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 4911f46c32cSGleb Smirnoff int s, err, s2; 492a8eb96d5SAlan Somers 4931f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 494a8eb96d5SAlan Somers 495a8eb96d5SAlan Somers /* Create the other socket */ 496a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 497a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 4981f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 499a8eb96d5SAlan Somers if (err != 0) { 500a8eb96d5SAlan Somers perror("connect"); 501a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 502a8eb96d5SAlan Somers } 503e594026dSAlan Somers close(s); 504e594026dSAlan Somers close(s2); 505a8eb96d5SAlan Somers } 506a8eb96d5SAlan Somers 5073bc122d2SGleb Smirnoff /* 5083bc122d2SGleb Smirnoff * An undocumented feature that we probably want to preserve: sending to 5093bc122d2SGleb Smirnoff * a socket that isn't yet accepted lands data on the socket. It can be 5103bc122d2SGleb Smirnoff * read after accept(2). 5113bc122d2SGleb Smirnoff */ 5123bc122d2SGleb Smirnoff ATF_TC_WITHOUT_HEAD(send_before_accept); 5133bc122d2SGleb Smirnoff ATF_TC_BODY(send_before_accept, tc) 5143bc122d2SGleb Smirnoff { 5153bc122d2SGleb Smirnoff const char buf[] = "hello"; 5163bc122d2SGleb Smirnoff char repl[sizeof(buf)]; 5173bc122d2SGleb Smirnoff const struct sockaddr_un *sun; 5183bc122d2SGleb Smirnoff int l, s, a; 5193bc122d2SGleb Smirnoff 5203bc122d2SGleb Smirnoff sun = mk_listening_socket(&l); 5213bc122d2SGleb Smirnoff 5223bc122d2SGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 5233bc122d2SGleb Smirnoff ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0); 5243bc122d2SGleb Smirnoff ATF_REQUIRE(send(s, &buf, sizeof(buf), 0) == sizeof(buf)); 5253bc122d2SGleb Smirnoff ATF_REQUIRE((a = accept(l, NULL, NULL)) != 1); 5263bc122d2SGleb Smirnoff ATF_REQUIRE(recv(a, &repl, sizeof(repl), 0) == sizeof(buf)); 5273bc122d2SGleb Smirnoff ATF_REQUIRE(strcmp(buf, repl) == 0); 5283bc122d2SGleb Smirnoff close(l); 5293bc122d2SGleb Smirnoff close(s); 5303bc122d2SGleb Smirnoff close(a); 5313bc122d2SGleb Smirnoff } 5323bc122d2SGleb Smirnoff 533*f9927821SGleb Smirnoff /* 534*f9927821SGleb Smirnoff * Test that close(2) of the peer ends in EPIPE when we try to send(2). 535*f9927821SGleb Smirnoff * Test both normal case as well as a peer that was not accept(2)-ed. 536*f9927821SGleb Smirnoff */ 537*f9927821SGleb Smirnoff static bool sigpipe_received = false; 538*f9927821SGleb Smirnoff static void 539*f9927821SGleb Smirnoff sigpipe_handler(int signo __unused) 540*f9927821SGleb Smirnoff { 541*f9927821SGleb Smirnoff sigpipe_received = true; 542*f9927821SGleb Smirnoff } 543*f9927821SGleb Smirnoff 544*f9927821SGleb Smirnoff ATF_TC_WITHOUT_HEAD(send_to_closed); 545*f9927821SGleb Smirnoff ATF_TC_BODY(send_to_closed, tc) 546*f9927821SGleb Smirnoff { 547*f9927821SGleb Smirnoff struct sigaction sa = { 548*f9927821SGleb Smirnoff .sa_handler = sigpipe_handler, 549*f9927821SGleb Smirnoff }; 550*f9927821SGleb Smirnoff const struct sockaddr_un *sun; 551*f9927821SGleb Smirnoff int l, s, a; 552*f9927821SGleb Smirnoff 553*f9927821SGleb Smirnoff ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); 554*f9927821SGleb Smirnoff ATF_REQUIRE(sigaction(SIGPIPE, &sa, NULL) == 0); 555*f9927821SGleb Smirnoff 556*f9927821SGleb Smirnoff sun = mk_listening_socket(&l); 557*f9927821SGleb Smirnoff 558*f9927821SGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 559*f9927821SGleb Smirnoff ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0); 560*f9927821SGleb Smirnoff ATF_REQUIRE((a = accept(l, NULL, NULL)) != 1); 561*f9927821SGleb Smirnoff close(a); 562*f9927821SGleb Smirnoff ATF_REQUIRE(send(s, &s, sizeof(s), 0) == -1); 563*f9927821SGleb Smirnoff ATF_REQUIRE(errno == EPIPE); 564*f9927821SGleb Smirnoff ATF_REQUIRE(sigpipe_received == true); 565*f9927821SGleb Smirnoff close(s); 566*f9927821SGleb Smirnoff 567*f9927821SGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 568*f9927821SGleb Smirnoff ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0); 569*f9927821SGleb Smirnoff close(l); 570*f9927821SGleb Smirnoff sigpipe_received = false; 571*f9927821SGleb Smirnoff ATF_REQUIRE(send(s, &s, sizeof(s), 0) == -1); 572*f9927821SGleb Smirnoff ATF_REQUIRE(errno == EPIPE); 573*f9927821SGleb Smirnoff ATF_REQUIRE(sigpipe_received == true); 574*f9927821SGleb Smirnoff close(s); 575*f9927821SGleb Smirnoff 576*f9927821SGleb Smirnoff sa.sa_handler = SIG_DFL; 577*f9927821SGleb Smirnoff ATF_REQUIRE(sigaction(SIGPIPE, &sa, NULL) == 0); 578*f9927821SGleb Smirnoff } 579*f9927821SGleb Smirnoff 580253d8a1fSGleb Smirnoff /* Implied connect is unix/dgram only feature. Fails on stream or seqpacket. */ 581253d8a1fSGleb Smirnoff ATF_TC_WITHOUT_HEAD(implied_connect); 582253d8a1fSGleb Smirnoff ATF_TC_BODY(implied_connect, tc) 583253d8a1fSGleb Smirnoff { 584253d8a1fSGleb Smirnoff const struct sockaddr_un *sun; 585253d8a1fSGleb Smirnoff int l, s; 586253d8a1fSGleb Smirnoff 587253d8a1fSGleb Smirnoff sun = mk_listening_socket(&l); 588253d8a1fSGleb Smirnoff 589253d8a1fSGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 590253d8a1fSGleb Smirnoff ATF_REQUIRE(sendto(s, &s, sizeof(s), 0, (struct sockaddr *)sun, 591253d8a1fSGleb Smirnoff sizeof(*sun)) == -1); 592253d8a1fSGleb Smirnoff ATF_REQUIRE(errno == ENOTCONN); 593253d8a1fSGleb Smirnoff close(l); 594253d8a1fSGleb Smirnoff close(s); 595253d8a1fSGleb Smirnoff } 596253d8a1fSGleb Smirnoff 597a8eb96d5SAlan Somers /* accept(2) can receive a connection */ 598a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(accept); 599a8eb96d5SAlan Somers ATF_TC_BODY(accept, tc) 600a8eb96d5SAlan Somers { 601a8eb96d5SAlan Somers int sv[2]; 602a8eb96d5SAlan Somers 603a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 604e594026dSAlan Somers close(sv[0]); 605e594026dSAlan Somers close(sv[1]); 606a8eb96d5SAlan Somers } 607a8eb96d5SAlan Somers 608a8eb96d5SAlan Somers 609a8eb96d5SAlan Somers /* Set O_NONBLOCK on the socket */ 610a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(fcntl_nonblock); 611a8eb96d5SAlan Somers ATF_TC_BODY(fcntl_nonblock, tc) 612a8eb96d5SAlan Somers { 613a8eb96d5SAlan Somers int s; 614a8eb96d5SAlan Somers 615a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 616a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 617a8eb96d5SAlan Somers if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) { 618a8eb96d5SAlan Somers perror("fcntl"); 619a8eb96d5SAlan Somers atf_tc_fail("fcntl failed"); 620a8eb96d5SAlan Somers } 621e594026dSAlan Somers close(s); 622a8eb96d5SAlan Somers } 623a8eb96d5SAlan Somers 624a8eb96d5SAlan Somers /* Resize the send and receive buffers */ 625a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_buffers); 626a8eb96d5SAlan Somers ATF_TC_BODY(resize_buffers, tc) 627a8eb96d5SAlan Somers { 628a8eb96d5SAlan Somers int s; 629a8eb96d5SAlan Somers int sndbuf = 12345; 630a8eb96d5SAlan Somers int rcvbuf = 23456; 631a8eb96d5SAlan Somers int xs, xr; 632a8eb96d5SAlan Somers socklen_t sl = sizeof(xs); 633a8eb96d5SAlan Somers 634a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 635a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 636a8eb96d5SAlan Somers 637a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 638a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF |\n"); 639a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 640a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 641a8eb96d5SAlan Somers printf("Default | %7d | %7d |\n", xs, xr); 642a8eb96d5SAlan Somers 643a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0){ 644a8eb96d5SAlan Somers perror("setsockopt"); 645a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 646a8eb96d5SAlan Somers } 647a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 648a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 649a8eb96d5SAlan Somers printf("After changing SNDBUF | %7d | %7d |\n", xs, xr); 650a8eb96d5SAlan Somers 651a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){ 652a8eb96d5SAlan Somers perror("setsockopt"); 653a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 654a8eb96d5SAlan Somers } 655a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 656a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 657a8eb96d5SAlan Somers printf("After changing RCVBUF | %7d | %7d |\n", xs, xr); 658e594026dSAlan Somers close(s); 659a8eb96d5SAlan Somers } 660a8eb96d5SAlan Somers 661a8eb96d5SAlan Somers /* 662a8eb96d5SAlan Somers * Resize the send and receive buffers of a connected socketpair 663a8eb96d5SAlan Somers * Print some useful debugging info too 664a8eb96d5SAlan Somers */ 665a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_connected_buffers); 666a8eb96d5SAlan Somers ATF_TC_BODY(resize_connected_buffers, tc) 667a8eb96d5SAlan Somers { 668a8eb96d5SAlan Somers int sv[2]; 669a8eb96d5SAlan Somers int sndbuf = 12345; 670a8eb96d5SAlan Somers int rcvbuf = 23456; 671a8eb96d5SAlan Somers int err; 672a8eb96d5SAlan Somers int ls, lr, rs, rr; 673a8eb96d5SAlan Somers socklen_t sl = sizeof(ls); 674a8eb96d5SAlan Somers 675a8eb96d5SAlan Somers /* setup the socket pair */ 676a8eb96d5SAlan Somers do_socketpair(sv); 677a8eb96d5SAlan Somers 678a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 679a8eb96d5SAlan Somers printf(" | Left Socket | Right Socket |\n"); 680a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF | SNDBUF | RCVBUF |\n"); 681a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 682a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 683a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 684a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 685a8eb96d5SAlan Somers printf("Default | %7d | %7d | %7d | %7d |\n", 686a8eb96d5SAlan Somers ls, lr, rs, rr); 687a8eb96d5SAlan Somers 688a8eb96d5SAlan Somers /* Update one side's send buffer */ 689a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 690a8eb96d5SAlan Somers if (err != 0){ 691a8eb96d5SAlan Somers perror("setsockopt"); 692a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 693a8eb96d5SAlan Somers } 694a8eb96d5SAlan Somers 695a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 696a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 697a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 698a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 699a8eb96d5SAlan Somers printf("After changing Left's SNDBUF | %7d | %7d | %7d | %7d |\n", 700a8eb96d5SAlan Somers ls, lr, rs, rr); 701a8eb96d5SAlan Somers 702a8eb96d5SAlan Somers /* Update the same side's receive buffer */ 703a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); 704a8eb96d5SAlan Somers if (err != 0){ 705a8eb96d5SAlan Somers perror("setsockopt"); 706a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 707a8eb96d5SAlan Somers } 708a8eb96d5SAlan Somers 709a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 710a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 711a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 712a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 713a8eb96d5SAlan Somers printf("After changing Left's RCVBUF | %7d | %7d | %7d | %7d |\n", 714a8eb96d5SAlan Somers ls, lr, rs, rr); 715e594026dSAlan Somers close(sv[0]); 716e594026dSAlan Somers close(sv[1]); 717a8eb96d5SAlan Somers } 718a8eb96d5SAlan Somers 719a8eb96d5SAlan Somers 720a8eb96d5SAlan Somers /* send(2) and recv(2) a single short record */ 721a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv); 722a8eb96d5SAlan Somers ATF_TC_BODY(send_recv, tc) 723a8eb96d5SAlan Somers { 724a8eb96d5SAlan Somers int sv[2]; 725a8eb96d5SAlan Somers const int bufsize = 64; 726a8eb96d5SAlan Somers const char *data = "data"; 727a8eb96d5SAlan Somers char recv_buf[bufsize]; 7285d5b721aSAlan Somers ssize_t datalen; 729a8eb96d5SAlan Somers ssize_t ssize, rsize; 730a8eb96d5SAlan Somers 731a8eb96d5SAlan Somers /* setup the socket pair */ 732a8eb96d5SAlan Somers do_socketpair(sv); 733a8eb96d5SAlan Somers 734a8eb96d5SAlan Somers /* send and receive a small packet */ 735a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 736a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 737a8eb96d5SAlan Somers if (ssize < 0) { 738a8eb96d5SAlan Somers perror("send"); 739a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 740a8eb96d5SAlan Somers } 741a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 742a8eb96d5SAlan Somers datalen, ssize); 743a8eb96d5SAlan Somers 744a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 745a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 746e594026dSAlan Somers close(sv[0]); 747e594026dSAlan Somers close(sv[1]); 748a8eb96d5SAlan Somers } 749a8eb96d5SAlan Somers 750a8eb96d5SAlan Somers /* sendto(2) and recvfrom(2) a single short record 751a8eb96d5SAlan Somers * According to The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 752a8eb96d5SAlan Somers * Edition, sendto(2) is exactly the same as send(2) on a connection-mode socket 753a8eb96d5SAlan Somers * 754a8eb96d5SAlan Somers * According to the same spec, not all protocols are required to provide the 755a8eb96d5SAlan Somers * source addres in recvfrom(2). 756a8eb96d5SAlan Somers */ 757a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendto_recvfrom); 758a8eb96d5SAlan Somers ATF_TC_BODY(sendto_recvfrom, tc) 759a8eb96d5SAlan Somers { 760983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 7611f46c32cSGleb Smirnoff const sockaddr_un *sun; 762983a2d91SEnji Cooper #endif 763a8eb96d5SAlan Somers struct sockaddr_storage from; 764a8eb96d5SAlan Somers int sv[2]; 765a8eb96d5SAlan Somers const int bufsize = 64; 766a8eb96d5SAlan Somers const char *data = "data"; 767a8eb96d5SAlan Somers char recv_buf[bufsize]; 7685d5b721aSAlan Somers ssize_t datalen; 769a8eb96d5SAlan Somers ssize_t ssize, rsize; 770a8eb96d5SAlan Somers socklen_t fromlen; 771a8eb96d5SAlan Somers 772a8eb96d5SAlan Somers /* setup the socket pair */ 773983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 7741f46c32cSGleb Smirnoff sun = 775983a2d91SEnji Cooper #endif 776983a2d91SEnji Cooper mk_pair_of_sockets(sv); 777a8eb96d5SAlan Somers 778a8eb96d5SAlan Somers /* send and receive a small packet */ 779a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 780a8eb96d5SAlan Somers ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0); 781a8eb96d5SAlan Somers if (ssize < 0) { 782a8eb96d5SAlan Somers perror("send"); 783a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 784a8eb96d5SAlan Somers } 785a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 786a8eb96d5SAlan Somers datalen, ssize); 787a8eb96d5SAlan Somers 788a8eb96d5SAlan Somers fromlen = sizeof(from); 789a8eb96d5SAlan Somers rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL, 790a8eb96d5SAlan Somers (struct sockaddr*)&from, &fromlen); 791a8eb96d5SAlan Somers if (ssize < 0) { 792a8eb96d5SAlan Somers perror("recvfrom"); 793a8eb96d5SAlan Somers atf_tc_fail("recvfrom returned < 0"); 794a8eb96d5SAlan Somers } 795a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 796a8eb96d5SAlan Somers 797983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 798a8eb96d5SAlan Somers /* 799a8eb96d5SAlan Somers * FreeBSD does not currently provide the source address for SEQ_PACKET 800a8eb96d5SAlan Somers * AF_UNIX sockets, and POSIX does not require it, so these two checks 801a8eb96d5SAlan Somers * are disabled. If FreeBSD gains that feature in the future, then 802a8eb96d5SAlan Somers * these checks may be reenabled 803a8eb96d5SAlan Somers */ 804983a2d91SEnji Cooper ATF_CHECK_EQ(PF_LOCAL, from.ss_family); 8051f46c32cSGleb Smirnoff ATF_CHECK_STREQ(sun->sun_path, ((struct sockaddr_un*)&from)->sun_path); 806983a2d91SEnji Cooper #endif 807e594026dSAlan Somers close(sv[0]); 808e594026dSAlan Somers close(sv[1]); 809a8eb96d5SAlan Somers } 810a8eb96d5SAlan Somers 811a8eb96d5SAlan Somers /* 812a8eb96d5SAlan Somers * send(2) and recv(2) a single short record with sockets created the 813a8eb96d5SAlan Somers * traditional way, involving bind, listen, connect, and accept 814a8eb96d5SAlan Somers */ 815a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_with_connect); 816a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_with_connect, tc) 817a8eb96d5SAlan Somers { 818a8eb96d5SAlan Somers int sv[2]; 819a8eb96d5SAlan Somers const int bufsize = 64; 820a8eb96d5SAlan Somers const char *data = "data"; 821a8eb96d5SAlan Somers char recv_buf[bufsize]; 8225d5b721aSAlan Somers ssize_t datalen; 823a8eb96d5SAlan Somers ssize_t ssize, rsize; 824a8eb96d5SAlan Somers 825a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 826a8eb96d5SAlan Somers 827a8eb96d5SAlan Somers /* send and receive a small packet */ 828a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 829a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 830a8eb96d5SAlan Somers if (ssize < 0) { 831a8eb96d5SAlan Somers perror("send"); 832a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 833a8eb96d5SAlan Somers } 834a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 835a8eb96d5SAlan Somers datalen, ssize); 836a8eb96d5SAlan Somers 837a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 838a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 839e594026dSAlan Somers close(sv[0]); 840e594026dSAlan Somers close(sv[1]); 841a8eb96d5SAlan Somers } 842a8eb96d5SAlan Somers 843a8eb96d5SAlan Somers /* send(2) should fail on a shutdown socket */ 844a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send); 845a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send, tc) 846a8eb96d5SAlan Somers { 8471f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 8484446a47aSSergey Kandaurov const char *data = "data"; 849fa5e5f53SEnji Cooper ssize_t datalen, ssize; 8504446a47aSSergey Kandaurov int s, err, s2; 851a8eb96d5SAlan Somers 8521f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 8534446a47aSSergey Kandaurov 8544446a47aSSergey Kandaurov /* Create the other socket */ 8554446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 8564446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 8571f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 8584446a47aSSergey Kandaurov if (err != 0) { 8594446a47aSSergey Kandaurov perror("connect"); 8604446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 8614446a47aSSergey Kandaurov } 8624446a47aSSergey Kandaurov 8634446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 864fa5e5f53SEnji Cooper datalen = strlen(data) + 1; /* +1 for the null */ 865a8eb96d5SAlan Somers /* USE MSG_NOSIGNAL so we don't get SIGPIPE */ 866fa5e5f53SEnji Cooper ssize = send(s2, data, datalen, MSG_EOR | MSG_NOSIGNAL); 867a8eb96d5SAlan Somers ATF_CHECK_EQ(EPIPE, errno); 868a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 869e594026dSAlan Somers close(s); 8704446a47aSSergey Kandaurov close(s2); 871a8eb96d5SAlan Somers } 872a8eb96d5SAlan Somers 873a8eb96d5SAlan Somers /* send(2) should cause SIGPIPE on a shutdown socket */ 874a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe); 875a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send_sigpipe, tc) 876a8eb96d5SAlan Somers { 8771f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 8784446a47aSSergey Kandaurov const char *data = "data"; 879fa5e5f53SEnji Cooper ssize_t datalen; 8804446a47aSSergey Kandaurov int s, err, s2; 881a8eb96d5SAlan Somers 8821f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 8834446a47aSSergey Kandaurov 8844446a47aSSergey Kandaurov /* Create the other socket */ 8854446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 8864446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 8871f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 8884446a47aSSergey Kandaurov if (err != 0) { 8894446a47aSSergey Kandaurov perror("connect"); 8904446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 8914446a47aSSergey Kandaurov } 8924446a47aSSergey Kandaurov 8934446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 894a8eb96d5SAlan Somers ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); 895fa5e5f53SEnji Cooper datalen = strlen(data) + 1; /* +1 for the null */ 8966dd202ceSJohn Baldwin (void)send(s2, data, datalen, MSG_EOR); 897a8eb96d5SAlan Somers ATF_CHECK_EQ(1, got_sigpipe); 898e594026dSAlan Somers close(s); 8994446a47aSSergey Kandaurov close(s2); 900a8eb96d5SAlan Somers } 901a8eb96d5SAlan Somers 902a8eb96d5SAlan Somers /* nonblocking send(2) and recv(2) a single short record */ 903a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 904a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_nonblocking, tc) 905a8eb96d5SAlan Somers { 906a8eb96d5SAlan Somers int sv[2]; 907a8eb96d5SAlan Somers const int bufsize = 64; 908a8eb96d5SAlan Somers const char *data = "data"; 909a8eb96d5SAlan Somers char recv_buf[bufsize]; 9105d5b721aSAlan Somers ssize_t datalen; 911a8eb96d5SAlan Somers ssize_t ssize, rsize; 912a8eb96d5SAlan Somers 913a8eb96d5SAlan Somers /* setup the socket pair */ 914a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 915a8eb96d5SAlan Somers 916a8eb96d5SAlan Somers /* Verify that there is nothing to receive */ 917a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 918a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 919a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 920a8eb96d5SAlan Somers 921a8eb96d5SAlan Somers /* send and receive a small packet */ 922a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 923a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 924a8eb96d5SAlan Somers if (ssize < 0) { 925a8eb96d5SAlan Somers perror("send"); 926a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 927a8eb96d5SAlan Somers } 928a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 929a8eb96d5SAlan Somers datalen, ssize); 930a8eb96d5SAlan Somers 931a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 932a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 933e594026dSAlan Somers close(sv[0]); 934e594026dSAlan Somers close(sv[1]); 935a8eb96d5SAlan Somers } 936a8eb96d5SAlan Somers 937a8eb96d5SAlan Somers /* 938a8eb96d5SAlan Somers * We should get EAGAIN if we try to send a message larger than the socket 939a8eb96d5SAlan Somers * buffer, with nonblocking sockets. Test with several different sockbuf sizes 940a8eb96d5SAlan Somers */ 941a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_8k); 942a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_8k, tc) 943a8eb96d5SAlan Somers { 944a8eb96d5SAlan Somers test_eagain(8192, 8192); 945a8eb96d5SAlan Somers } 946a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_128k); 947a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_128k, tc) 948a8eb96d5SAlan Somers { 949a8eb96d5SAlan Somers test_eagain(8192, 131072); 950a8eb96d5SAlan Somers } 951a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_8k); 952a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_8k, tc) 953a8eb96d5SAlan Somers { 954a8eb96d5SAlan Somers test_eagain(131072, 8192); 955a8eb96d5SAlan Somers } 956a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_128k); 957a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_128k, tc) 958a8eb96d5SAlan Somers { 959a8eb96d5SAlan Somers test_eagain(131072, 131072); 960a8eb96d5SAlan Somers } 961a8eb96d5SAlan Somers 962a8eb96d5SAlan Somers 963a8eb96d5SAlan Somers /* 964a8eb96d5SAlan Somers * nonblocking send(2) and recv(2) of several records, which should collectively 965a8eb96d5SAlan Somers * fill up the send buffer but not the receive buffer 966a8eb96d5SAlan Somers */ 967a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(rcvbuf_oversized); 968a8eb96d5SAlan Somers ATF_TC_BODY(rcvbuf_oversized, tc) 969a8eb96d5SAlan Somers { 9705d5b721aSAlan Somers int i; 971a8eb96d5SAlan Somers int sv[2]; 9723be7751dSJulio Merino const ssize_t pktsize = 1024; 973ea703329SBrooks Davis const int sndbufsize = 8192; 974ea703329SBrooks Davis const int rcvbufsize = 131072; 9755d5b721aSAlan Somers const size_t geometric_mean_bufsize = 32768; 9765d5b721aSAlan Somers const int numpkts = geometric_mean_bufsize / pktsize; 977a8eb96d5SAlan Somers char sndbuf[pktsize]; 978a8eb96d5SAlan Somers char recv_buf[pktsize]; 979a8eb96d5SAlan Somers ssize_t ssize, rsize; 980a8eb96d5SAlan Somers 981a8eb96d5SAlan Somers /* setup the socket pair */ 982a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 9835d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 9845d5b721aSAlan Somers sizeof(sndbufsize))); 9855d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 9865d5b721aSAlan Somers sizeof(rcvbufsize))); 987a8eb96d5SAlan Somers 988a8eb96d5SAlan Somers /* 989a8eb96d5SAlan Somers * Send and receive packets that are collectively greater than the send 990a8eb96d5SAlan Somers * buffer, but less than the receive buffer 991a8eb96d5SAlan Somers */ 9925d5b721aSAlan Somers for (i=0; i < numpkts; i++) { 993a8eb96d5SAlan Somers /* Fill the buffer */ 994a8eb96d5SAlan Somers memset(sndbuf, i, pktsize); 995a8eb96d5SAlan Somers 996a8eb96d5SAlan Somers /* send the packet */ 997a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 998a8eb96d5SAlan Somers if (ssize < 0) { 999a8eb96d5SAlan Somers perror("send"); 1000a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 1001a8eb96d5SAlan Somers } 1002a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 1003a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, ssize); 1004a8eb96d5SAlan Somers 1005a8eb96d5SAlan Somers /* Receive it */ 1006a8eb96d5SAlan Somers 1007a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 1008a8eb96d5SAlan Somers if (rsize < 0) { 1009a8eb96d5SAlan Somers perror("recv"); 1010a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 1011a8eb96d5SAlan Somers } 1012a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 1013a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, rsize); 1014a8eb96d5SAlan Somers 1015a8eb96d5SAlan Somers /* Verify the contents */ 1016a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), 1017a8eb96d5SAlan Somers "Received data miscompare"); 1018a8eb96d5SAlan Somers } 1019a8eb96d5SAlan Somers 1020a8eb96d5SAlan Somers /* Trying to receive again should return EAGAIN */ 1021a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 1022a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 1023a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 1024e594026dSAlan Somers close(sv[0]); 1025e594026dSAlan Somers close(sv[1]); 1026a8eb96d5SAlan Somers } 1027a8eb96d5SAlan Somers 1028a8eb96d5SAlan Somers /* 1029a8eb96d5SAlan Somers * Simulate the behavior of a blocking pipe. The sender will send until his 1030a8eb96d5SAlan Somers * buffer fills up, then we'll simulate a scheduler switch that will allow the 1031a8eb96d5SAlan Somers * receiver to read until his buffer empties. Repeat the process until the 1032a8eb96d5SAlan Somers * transfer is complete. 1033a8eb96d5SAlan Somers * Repeat the test with multiple send and receive buffer sizes 1034a8eb96d5SAlan Somers */ 1035a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k); 1036a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_8k, tc) 1037a8eb96d5SAlan Somers { 1038a8eb96d5SAlan Somers test_pipe_simulator(8192, 8192); 1039a8eb96d5SAlan Somers } 1040a8eb96d5SAlan Somers 1041a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k); 1042a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_128k, tc) 1043a8eb96d5SAlan Somers { 1044a8eb96d5SAlan Somers test_pipe_simulator(8192, 131072); 1045a8eb96d5SAlan Somers } 1046a8eb96d5SAlan Somers 1047a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k); 1048a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_8k, tc) 1049a8eb96d5SAlan Somers { 1050a8eb96d5SAlan Somers test_pipe_simulator(131072, 8192); 1051a8eb96d5SAlan Somers } 1052a8eb96d5SAlan Somers 1053a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k); 1054a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_128k, tc) 1055a8eb96d5SAlan Somers { 1056a8eb96d5SAlan Somers test_pipe_simulator(131072, 131072); 1057a8eb96d5SAlan Somers } 1058a8eb96d5SAlan Somers 1059a8eb96d5SAlan Somers /* 1060a8eb96d5SAlan Somers * Test blocking I/O by passing data between two threads. The total amount of 1061a8eb96d5SAlan Somers * data will be >> buffer size to force blocking. Repeat the test with multiple 1062a8eb96d5SAlan Somers * send and receive buffer sizes 1063a8eb96d5SAlan Somers */ 1064a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_8k); 1065a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_8k, tc) 1066a8eb96d5SAlan Somers { 1067a8eb96d5SAlan Somers test_pipe(8192, 8192); 1068a8eb96d5SAlan Somers } 1069a8eb96d5SAlan Somers 1070a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_128k); 1071a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_128k, tc) 1072a8eb96d5SAlan Somers { 1073a8eb96d5SAlan Somers test_pipe(8192, 131072); 1074a8eb96d5SAlan Somers } 1075a8eb96d5SAlan Somers 1076a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_8k); 1077a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_8k, tc) 1078a8eb96d5SAlan Somers { 1079a8eb96d5SAlan Somers test_pipe(131072, 8192); 1080a8eb96d5SAlan Somers } 1081a8eb96d5SAlan Somers 1082a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_128k); 1083a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_128k, tc) 1084a8eb96d5SAlan Somers { 1085a8eb96d5SAlan Somers test_pipe(131072, 131072); 1086a8eb96d5SAlan Somers } 1087a8eb96d5SAlan Somers 1088a8eb96d5SAlan Somers 1089a8eb96d5SAlan Somers /* 1090a8eb96d5SAlan Somers * Test single-packet I/O with and without blocking, with symmetric buffers of 1091a8eb96d5SAlan Somers * various sizes 1092a8eb96d5SAlan Somers */ 1093a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k); 1094a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k, tc) 1095a8eb96d5SAlan Somers { 1096a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, true); 1097a8eb96d5SAlan Somers } 1098a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k); 1099a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k, tc) 1100a8eb96d5SAlan Somers { 1101a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, true); 1102a8eb96d5SAlan Somers } 1103a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k); 1104a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k, tc) 1105a8eb96d5SAlan Somers { 1106a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, true); 1107a8eb96d5SAlan Somers } 1108a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k); 1109a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k, tc) 1110a8eb96d5SAlan Somers { 1111a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, true); 1112a8eb96d5SAlan Somers } 1113a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k); 1114a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k, tc) 1115a8eb96d5SAlan Somers { 1116a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, true); 1117a8eb96d5SAlan Somers } 1118a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking); 1119a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k_nonblocking, tc) 1120a8eb96d5SAlan Somers { 1121a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, false); 1122a8eb96d5SAlan Somers } 1123a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking); 1124a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k_nonblocking, tc) 1125a8eb96d5SAlan Somers { 1126a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, false); 1127a8eb96d5SAlan Somers } 1128a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking); 1129a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k_nonblocking, tc) 1130a8eb96d5SAlan Somers { 1131a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, false); 1132a8eb96d5SAlan Somers } 1133a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking); 1134a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k_nonblocking, tc) 1135a8eb96d5SAlan Somers { 1136a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, false); 1137a8eb96d5SAlan Somers } 1138a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking); 1139a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k_nonblocking, tc) 1140a8eb96d5SAlan Somers { 1141a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, false); 1142a8eb96d5SAlan Somers } 1143a8eb96d5SAlan Somers 1144eb338e23SGleb Smirnoff ATF_TC(random_eor_and_waitall); 1145eb338e23SGleb Smirnoff ATF_TC_HEAD(random_eor_and_waitall, tc) 1146eb338e23SGleb Smirnoff { 1147eb338e23SGleb Smirnoff atf_tc_set_md_var(tc, "descr", "Test random sized send/recv with " 1148eb338e23SGleb Smirnoff "randomly placed MSG_EOR and randomly applied MSG_WAITALL on " 1149eb338e23SGleb Smirnoff "PF_UNIX/SOCK_SEQPACKET"); 1150eb338e23SGleb Smirnoff } 1151eb338e23SGleb Smirnoff 1152eb338e23SGleb Smirnoff struct random_eor_params { 1153eb338e23SGleb Smirnoff u_long recvspace; 1154eb338e23SGleb Smirnoff char *sendbuf; 1155eb338e23SGleb Smirnoff size_t *records; 1156eb338e23SGleb Smirnoff u_int nrecords; 1157eb338e23SGleb Smirnoff int sock; 1158eb338e23SGleb Smirnoff u_short seed[6]; 1159eb338e23SGleb Smirnoff }; 1160eb338e23SGleb Smirnoff 1161eb338e23SGleb Smirnoff #define RANDOM_TESTSIZE ((size_t)100 * 1024 * 1024) 1162eb338e23SGleb Smirnoff /* Below defines are factor of recvspace. */ 1163eb338e23SGleb Smirnoff #define RANDOM_MAXRECORD 10 1164eb338e23SGleb Smirnoff #define RANDOM_SENDSIZE 2 1165eb338e23SGleb Smirnoff #define RANDOM_RECVSIZE 4 1166eb338e23SGleb Smirnoff 1167eb338e23SGleb Smirnoff static void * 1168eb338e23SGleb Smirnoff sending_thread(void *arg) 1169eb338e23SGleb Smirnoff { 1170eb338e23SGleb Smirnoff struct random_eor_params *params = arg; 1171eb338e23SGleb Smirnoff size_t off = 0; 1172eb338e23SGleb Smirnoff int eor = 0; 1173eb338e23SGleb Smirnoff 1174eb338e23SGleb Smirnoff while (off < RANDOM_TESTSIZE) { 1175eb338e23SGleb Smirnoff ssize_t len; 1176eb338e23SGleb Smirnoff int flags; 1177eb338e23SGleb Smirnoff 1178eb338e23SGleb Smirnoff len = nrand48(¶ms->seed[3]) % 1179eb338e23SGleb Smirnoff (RANDOM_SENDSIZE * params->recvspace); 1180eb338e23SGleb Smirnoff if (off + len >= params->records[eor]) { 1181eb338e23SGleb Smirnoff len = params->records[eor] - off; 1182eb338e23SGleb Smirnoff flags = MSG_EOR; 1183eb338e23SGleb Smirnoff eor++; 1184eb338e23SGleb Smirnoff } else 1185eb338e23SGleb Smirnoff flags = 0; 1186eb338e23SGleb Smirnoff ATF_REQUIRE(send(params->sock, ¶ms->sendbuf[off], len, 1187eb338e23SGleb Smirnoff flags) == len); 1188eb338e23SGleb Smirnoff off += len; 1189eb338e23SGleb Smirnoff #ifdef DEBUG 1190eb338e23SGleb Smirnoff printf("send %zd%s\n", off, flags ? " EOR" : ""); 1191eb338e23SGleb Smirnoff #endif 1192eb338e23SGleb Smirnoff } 1193eb338e23SGleb Smirnoff 1194eb338e23SGleb Smirnoff return (NULL); 1195eb338e23SGleb Smirnoff } 1196eb338e23SGleb Smirnoff 1197eb338e23SGleb Smirnoff ATF_TC_BODY(random_eor_and_waitall, tc) 1198eb338e23SGleb Smirnoff { 1199eb338e23SGleb Smirnoff struct random_eor_params params; 1200eb338e23SGleb Smirnoff void *recvbuf; 1201eb338e23SGleb Smirnoff pthread_t t; 1202eb338e23SGleb Smirnoff size_t off; 1203eb338e23SGleb Smirnoff int fd[2], eor; 1204eb338e23SGleb Smirnoff 1205eb338e23SGleb Smirnoff arc4random_buf(params.seed, sizeof(params.seed)); 1206eb338e23SGleb Smirnoff printf("Using seed:"); 1207eb338e23SGleb Smirnoff for (u_int i = 0; i < (u_int)sizeof(params.seed)/sizeof(u_short); i++) 1208eb338e23SGleb Smirnoff printf(" 0x%.4x,", params.seed[i]); 1209eb338e23SGleb Smirnoff printf("\n"); 1210eb338e23SGleb Smirnoff 1211eb338e23SGleb Smirnoff ATF_REQUIRE((params.sendbuf = malloc(RANDOM_TESTSIZE)) != NULL); 1212eb338e23SGleb Smirnoff for (u_int i = 0; i < RANDOM_TESTSIZE / (u_int )sizeof(long); i++) 1213eb338e23SGleb Smirnoff ((long *)params.sendbuf)[i] = nrand48(¶ms.seed[0]); 1214eb338e23SGleb Smirnoff 1215eb338e23SGleb Smirnoff ATF_REQUIRE(sysctlbyname("net.local.stream.recvspace", 1216eb338e23SGleb Smirnoff ¶ms.recvspace, &(size_t){sizeof(u_long)}, NULL, 0) != -1); 1217eb338e23SGleb Smirnoff ATF_REQUIRE((recvbuf = 1218eb338e23SGleb Smirnoff malloc(RANDOM_RECVSIZE * params.recvspace)) != NULL); 1219eb338e23SGleb Smirnoff 1220eb338e23SGleb Smirnoff params.nrecords = 2 * RANDOM_TESTSIZE / 1221eb338e23SGleb Smirnoff (RANDOM_MAXRECORD * params.recvspace); 1222eb338e23SGleb Smirnoff 1223eb338e23SGleb Smirnoff ATF_REQUIRE((params.records = 1224eb338e23SGleb Smirnoff malloc(params.nrecords * sizeof(size_t *))) != NULL); 1225eb338e23SGleb Smirnoff off = 0; 1226eb338e23SGleb Smirnoff for (u_int i = 0; i < params.nrecords; i++) { 1227eb338e23SGleb Smirnoff off += 1 + nrand48(¶ms.seed[0]) % 1228eb338e23SGleb Smirnoff (RANDOM_MAXRECORD * params.recvspace); 1229eb338e23SGleb Smirnoff if (off > RANDOM_TESTSIZE) { 1230eb338e23SGleb Smirnoff params.nrecords = i; 1231eb338e23SGleb Smirnoff break; 1232eb338e23SGleb Smirnoff } 1233eb338e23SGleb Smirnoff params.records[i] = off; 1234eb338e23SGleb Smirnoff } 1235eb338e23SGleb Smirnoff params.records[params.nrecords - 1] = RANDOM_TESTSIZE; 1236eb338e23SGleb Smirnoff 1237eb338e23SGleb Smirnoff ATF_REQUIRE(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, fd) == 0); 1238eb338e23SGleb Smirnoff params.sock = fd[0]; 1239eb338e23SGleb Smirnoff ATF_REQUIRE(pthread_create(&t, NULL, sending_thread, ¶ms) == 0); 1240eb338e23SGleb Smirnoff 1241eb338e23SGleb Smirnoff off = 0; 1242eb338e23SGleb Smirnoff eor = 0; 1243eb338e23SGleb Smirnoff while (off < RANDOM_TESTSIZE) { 1244eb338e23SGleb Smirnoff struct iovec iov = { 1245eb338e23SGleb Smirnoff .iov_base = recvbuf, 1246eb338e23SGleb Smirnoff .iov_len = nrand48(¶ms.seed[0]) % 1247eb338e23SGleb Smirnoff (RANDOM_RECVSIZE * params.recvspace) 1248eb338e23SGleb Smirnoff }; 1249eb338e23SGleb Smirnoff struct msghdr hdr = { 1250eb338e23SGleb Smirnoff .msg_iov = &iov, 1251eb338e23SGleb Smirnoff .msg_iovlen = 1, 1252eb338e23SGleb Smirnoff }; 1253eb338e23SGleb Smirnoff size_t len; 1254eb338e23SGleb Smirnoff int waitall = iov.iov_len & 0x1 ? MSG_WAITALL : 0; 1255eb338e23SGleb Smirnoff 1256eb338e23SGleb Smirnoff len = recvmsg(fd[1], &hdr, waitall); 1257eb338e23SGleb Smirnoff if (waitall && !(hdr.msg_flags & MSG_EOR)) 1258eb338e23SGleb Smirnoff ATF_CHECK_EQ_MSG(len, iov.iov_len, 1259eb338e23SGleb Smirnoff "recvmsg(MSG_WAITALL): %zd, expected %zd", 1260eb338e23SGleb Smirnoff len, iov.iov_len); 1261eb338e23SGleb Smirnoff if (off + len == params.records[eor]) { 1262eb338e23SGleb Smirnoff ATF_REQUIRE_MSG(hdr.msg_flags & MSG_EOR, 1263eb338e23SGleb Smirnoff "recvmsg(): expected EOR @ %zd", off + len); 1264eb338e23SGleb Smirnoff eor++; 1265eb338e23SGleb Smirnoff } else { 1266eb338e23SGleb Smirnoff ATF_REQUIRE_MSG(off + len < params.records[eor], 1267eb338e23SGleb Smirnoff "recvmsg() past EOR: %zd, expected %zd", 1268eb338e23SGleb Smirnoff off + len, params.records[eor]); 1269eb338e23SGleb Smirnoff ATF_REQUIRE_MSG(!(hdr.msg_flags & MSG_EOR), 1270eb338e23SGleb Smirnoff "recvmsg() spurious EOR at %zd, expected %zd", 1271eb338e23SGleb Smirnoff off + len, params.records[eor]); 1272eb338e23SGleb Smirnoff } 1273eb338e23SGleb Smirnoff ATF_REQUIRE_MSG(0 == memcmp(params.sendbuf + off, recvbuf, len), 1274eb338e23SGleb Smirnoff "data corruption past %zd", off); 1275eb338e23SGleb Smirnoff off += len; 1276eb338e23SGleb Smirnoff #ifdef DEBUG 1277eb338e23SGleb Smirnoff printf("recv %zd%s %zd/%zd%s\n", off, 1278eb338e23SGleb Smirnoff (hdr.msg_flags & MSG_EOR) ? " EOR" : "", 1279eb338e23SGleb Smirnoff len, iov.iov_len, 1280eb338e23SGleb Smirnoff waitall ? " WAITALL" : ""); 1281eb338e23SGleb Smirnoff #endif 1282eb338e23SGleb Smirnoff } 1283eb338e23SGleb Smirnoff 1284eb338e23SGleb Smirnoff ATF_REQUIRE(pthread_join(t, NULL) == 0); 1285eb338e23SGleb Smirnoff free(params.sendbuf); 1286eb338e23SGleb Smirnoff free(recvbuf); 1287eb338e23SGleb Smirnoff free(params.records); 1288eb338e23SGleb Smirnoff } 1289a8eb96d5SAlan Somers 1290a8eb96d5SAlan Somers /* 1291a8eb96d5SAlan Somers * Main. 1292a8eb96d5SAlan Somers */ 1293a8eb96d5SAlan Somers 1294a8eb96d5SAlan Somers ATF_TP_ADD_TCS(tp) 1295a8eb96d5SAlan Somers { 1296a8eb96d5SAlan Somers /* Basic creation and connection tests */ 1297a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socket); 1298a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socketpair); 1299a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_unbound); 1300a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, bind); 1301a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_bound); 1302a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, connect); 1303a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, accept); 1304a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, fcntl_nonblock); 1305a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_buffers); 1306a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_connected_buffers); 1307a8eb96d5SAlan Somers 1308a8eb96d5SAlan Somers /* Unthreaded I/O tests */ 1309a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv); 1310a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_nonblocking); 1311a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_with_connect); 1312a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendto_recvfrom); 13133bc122d2SGleb Smirnoff ATF_TP_ADD_TC(tp, send_before_accept); 1314*f9927821SGleb Smirnoff ATF_TP_ADD_TC(tp, send_to_closed); 1315253d8a1fSGleb Smirnoff ATF_TP_ADD_TC(tp, implied_connect); 1316a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send); 1317a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send_sigpipe); 1318a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_8k); 1319a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_128k); 1320a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_8k); 1321a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_128k); 1322a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k); 1323a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k); 1324a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k); 1325a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k); 1326a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k); 1327a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking); 1328a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking); 1329a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking); 1330a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking); 1331a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking); 1332a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, rcvbuf_oversized); 1333a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k); 1334a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k); 1335a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k); 1336a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k); 1337a8eb96d5SAlan Somers 1338a8eb96d5SAlan Somers /* Threaded I/O tests with blocking sockets */ 1339a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_8k); 1340a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_128k); 1341a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_8k); 1342a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_128k); 1343eb338e23SGleb Smirnoff ATF_TP_ADD_TC(tp, random_eor_and_waitall); 1344a8eb96d5SAlan Somers 1345a8eb96d5SAlan Somers return atf_no_error(); 1346a8eb96d5SAlan Somers } 1347