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) { 2630b499297SGleb Smirnoff if (errno == EAGAIN) 264a8eb96d5SAlan Somers currently_sending = false; 265a8eb96d5SAlan Somers else { 266a8eb96d5SAlan Somers perror("send"); 267a8eb96d5SAlan Somers atf_tc_fail("send failed"); 268a8eb96d5SAlan Somers } 269a8eb96d5SAlan Somers } else { 270a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 271a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 272a8eb96d5SAlan Somers pktsize, ssize); 273a8eb96d5SAlan Somers num_sent++; 274a8eb96d5SAlan Somers } 275a8eb96d5SAlan Somers } else { 276a8eb96d5SAlan Somers /* The simulated receiving process */ 277a8eb96d5SAlan Somers rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL); 278a8eb96d5SAlan Somers if (rsize < 0) { 279a8eb96d5SAlan Somers if (errno == EAGAIN) { 280a8eb96d5SAlan Somers currently_sending = true; 281a8eb96d5SAlan Somers ATF_REQUIRE_MSG(num_sent < numpkts, 282a8eb96d5SAlan Somers "Packets were lost!"); 283a8eb96d5SAlan Somers } 284a8eb96d5SAlan Somers else { 285a8eb96d5SAlan Somers perror("recv"); 286a8eb96d5SAlan Somers atf_tc_fail("recv failed"); 287a8eb96d5SAlan Somers } 288a8eb96d5SAlan Somers } else { 289a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 290a8eb96d5SAlan Somers "expected %zd=recv(...) but got %zd", 291a8eb96d5SAlan Somers pktsize, rsize); 292a8eb96d5SAlan Somers memset(comparebuf, num_received, pktsize); 293a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf, 294a8eb96d5SAlan Somers pktsize), 295a8eb96d5SAlan Somers "Received data miscompare"); 296a8eb96d5SAlan Somers num_received++; 297a8eb96d5SAlan Somers } 298a8eb96d5SAlan Somers } 299a8eb96d5SAlan Somers } 300e594026dSAlan Somers close(sv[0]); 301e594026dSAlan Somers close(sv[1]); 302a8eb96d5SAlan Somers } 303a8eb96d5SAlan Somers 304a8eb96d5SAlan Somers typedef struct { 305a8eb96d5SAlan Somers ssize_t pktsize; 306a8eb96d5SAlan Somers int numpkts; 307a8eb96d5SAlan Somers int so; 308a8eb96d5SAlan Somers } test_pipe_thread_data_t; 309a8eb96d5SAlan Somers 310a8eb96d5SAlan Somers static void* 311a8eb96d5SAlan Somers test_pipe_writer(void* args) 312a8eb96d5SAlan Somers { 313a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 314a8eb96d5SAlan Somers char sndbuf[td->pktsize]; 315a8eb96d5SAlan Somers ssize_t ssize; 316a8eb96d5SAlan Somers int i; 317a8eb96d5SAlan Somers 318a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 319a8eb96d5SAlan Somers memset(sndbuf, i, td->pktsize); 320a8eb96d5SAlan Somers ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR); 321a8eb96d5SAlan Somers if (ssize < 0) { 322a8eb96d5SAlan Somers perror("send"); 323a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 324a8eb96d5SAlan Somers } 325a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, ssize, 326a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 327a8eb96d5SAlan Somers td->pktsize, ssize); 328a8eb96d5SAlan Somers } 329a8eb96d5SAlan Somers return (0); 330a8eb96d5SAlan Somers } 331a8eb96d5SAlan Somers 332a8eb96d5SAlan Somers static void* 333a8eb96d5SAlan Somers test_pipe_reader(void* args) 334a8eb96d5SAlan Somers { 335a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 336a8eb96d5SAlan Somers char rcvbuf[td->pktsize]; 337a8eb96d5SAlan Somers char comparebuf[td->pktsize]; 338a8eb96d5SAlan Somers ssize_t rsize; 339a8eb96d5SAlan Somers int i, d; 340a8eb96d5SAlan Somers 341a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 342a8eb96d5SAlan Somers memset(comparebuf, i, td->pktsize); 343a8eb96d5SAlan Somers rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL); 344a8eb96d5SAlan Somers if (rsize < 0) { 345a8eb96d5SAlan Somers perror("recv"); 346a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 347a8eb96d5SAlan Somers } 348a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, rsize, 349a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 350a8eb96d5SAlan Somers td->pktsize, rsize); 351a8eb96d5SAlan Somers d = memcmp(comparebuf, rcvbuf, td->pktsize); 352a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, d, 353a8eb96d5SAlan Somers "Received data miscompare on packet %d", i); 354a8eb96d5SAlan Somers } 355a8eb96d5SAlan Somers return (0); 356a8eb96d5SAlan Somers } 357a8eb96d5SAlan Somers 358a8eb96d5SAlan Somers 3595d5b721aSAlan Somers static void 360ea703329SBrooks Davis test_pipe(int sndbufsize, int rcvbufsize) 361a8eb96d5SAlan Somers { 362a8eb96d5SAlan Somers test_pipe_thread_data_t writer_data, reader_data; 363a8eb96d5SAlan Somers pthread_t writer, reader; 364a8eb96d5SAlan Somers int sv[2]; 365a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 366a8eb96d5SAlan Somers int numpkts; 367a8eb96d5SAlan Somers 368a8eb96d5SAlan Somers /* setup the socket pair */ 369a8eb96d5SAlan Somers do_socketpair(sv); 370a8eb96d5SAlan Somers /* Setup the buffers */ 371a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 372a8eb96d5SAlan Somers sizeof(sndbufsize))); 373a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 374a8eb96d5SAlan Somers sizeof(rcvbufsize))); 375a8eb96d5SAlan Somers 376a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 377a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 378a8eb96d5SAlan Somers 379a8eb96d5SAlan Somers /* Start the child threads */ 380a8eb96d5SAlan Somers writer_data.pktsize = pktsize; 381a8eb96d5SAlan Somers writer_data.numpkts = numpkts; 382a8eb96d5SAlan Somers writer_data.so = sv[0]; 383a8eb96d5SAlan Somers reader_data.pktsize = pktsize; 384a8eb96d5SAlan Somers reader_data.numpkts = numpkts; 385a8eb96d5SAlan Somers reader_data.so = sv[1]; 386a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer, 387a8eb96d5SAlan Somers (void*)&writer_data)); 3888de34a88SAlan Somers /* 3898de34a88SAlan Somers * Give the writer time to start writing, and hopefully block, before 3908de34a88SAlan Somers * starting the reader. This increases the likelihood of the test case 3918de34a88SAlan Somers * failing due to PR kern/185812 3928de34a88SAlan Somers */ 3938de34a88SAlan Somers usleep(1000); 394a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader, 395a8eb96d5SAlan Somers (void*)&reader_data)); 396a8eb96d5SAlan Somers 397a8eb96d5SAlan Somers /* Join the children */ 398a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(writer, NULL)); 399a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(reader, NULL)); 400e594026dSAlan Somers close(sv[0]); 401e594026dSAlan Somers close(sv[1]); 402a8eb96d5SAlan Somers } 403a8eb96d5SAlan Somers 404a8eb96d5SAlan Somers 405a8eb96d5SAlan Somers /* 406a8eb96d5SAlan Somers * Test Cases 407a8eb96d5SAlan Somers */ 408a8eb96d5SAlan Somers 409a8eb96d5SAlan Somers /* Create a SEQPACKET socket */ 410a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socket); 411a8eb96d5SAlan Somers ATF_TC_BODY(create_socket, tc) 412a8eb96d5SAlan Somers { 413a8eb96d5SAlan Somers int s; 414a8eb96d5SAlan Somers 415a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 4166addc01eSAlan Somers ATF_REQUIRE(s >= 0); 417e594026dSAlan Somers close(s); 418a8eb96d5SAlan Somers } 419a8eb96d5SAlan Somers 420a8eb96d5SAlan Somers /* Create SEQPACKET sockets using socketpair(2) */ 421a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socketpair); 422a8eb96d5SAlan Somers ATF_TC_BODY(create_socketpair, tc) 423a8eb96d5SAlan Somers { 424a8eb96d5SAlan Somers int sv[2]; 425a8eb96d5SAlan Somers int s; 426a8eb96d5SAlan Somers 427a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 428a8eb96d5SAlan Somers ATF_CHECK_EQ(0, s); 429a8eb96d5SAlan Somers ATF_CHECK(sv[0] >= 0); 430a8eb96d5SAlan Somers ATF_CHECK(sv[1] >= 0); 431a8eb96d5SAlan Somers ATF_CHECK(sv[0] != sv[1]); 432e594026dSAlan Somers close(sv[0]); 433e594026dSAlan Somers close(sv[1]); 434a8eb96d5SAlan Somers } 435a8eb96d5SAlan Somers 436a8eb96d5SAlan Somers /* Call listen(2) without first calling bind(2). It should fail */ 437a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_unbound); 438a8eb96d5SAlan Somers ATF_TC_BODY(listen_unbound, tc) 439a8eb96d5SAlan Somers { 440a8eb96d5SAlan Somers int s, r; 441a8eb96d5SAlan Somers 442a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 443a8eb96d5SAlan Somers ATF_REQUIRE(s > 0); 444a8eb96d5SAlan Somers r = listen(s, -1); 445a8eb96d5SAlan Somers /* expect listen to fail since we haven't called bind(2) */ 446a8eb96d5SAlan Somers ATF_CHECK(r != 0); 447e594026dSAlan Somers close(s); 448a8eb96d5SAlan Somers } 449a8eb96d5SAlan Somers 450a8eb96d5SAlan Somers /* Bind the socket to a file */ 451a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(bind); 452a8eb96d5SAlan Somers ATF_TC_BODY(bind, tc) 453a8eb96d5SAlan Somers { 454a8eb96d5SAlan Somers struct sockaddr_un sun; 455a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 456a8eb96d5SAlan Somers const char *path = "sock"; 457a8eb96d5SAlan Somers int s, r; 458a8eb96d5SAlan Somers 459a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 460a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 461a8eb96d5SAlan Somers 462a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 463a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 464a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 465a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 466a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 467a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 468e594026dSAlan Somers close(s); 469a8eb96d5SAlan Somers } 470a8eb96d5SAlan Somers 471a8eb96d5SAlan Somers /* listen(2) a socket that is already bound(2) should succeed */ 472a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_bound); 473a8eb96d5SAlan Somers ATF_TC_BODY(listen_bound, tc) 474a8eb96d5SAlan Somers { 4751f46c32cSGleb Smirnoff int s; 476a8eb96d5SAlan Somers 4771f46c32cSGleb Smirnoff (void)mk_listening_socket(&s); 478e594026dSAlan Somers close(s); 479a8eb96d5SAlan Somers } 480a8eb96d5SAlan Somers 481a8eb96d5SAlan Somers /* connect(2) can make a connection */ 482a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(connect); 483a8eb96d5SAlan Somers ATF_TC_BODY(connect, tc) 484a8eb96d5SAlan Somers { 4851f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 4861f46c32cSGleb Smirnoff int s, err, s2; 487a8eb96d5SAlan Somers 4881f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 489a8eb96d5SAlan Somers 490a8eb96d5SAlan Somers /* Create the other socket */ 491a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 492a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 4931f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 494a8eb96d5SAlan Somers if (err != 0) { 495a8eb96d5SAlan Somers perror("connect"); 496a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 497a8eb96d5SAlan Somers } 498e594026dSAlan Somers close(s); 499e594026dSAlan Somers close(s2); 500a8eb96d5SAlan Somers } 501a8eb96d5SAlan Somers 5023bc122d2SGleb Smirnoff /* 5033bc122d2SGleb Smirnoff * An undocumented feature that we probably want to preserve: sending to 5043bc122d2SGleb Smirnoff * a socket that isn't yet accepted lands data on the socket. It can be 5053bc122d2SGleb Smirnoff * read after accept(2). 5063bc122d2SGleb Smirnoff */ 5073bc122d2SGleb Smirnoff ATF_TC_WITHOUT_HEAD(send_before_accept); 5083bc122d2SGleb Smirnoff ATF_TC_BODY(send_before_accept, tc) 5093bc122d2SGleb Smirnoff { 5103bc122d2SGleb Smirnoff const char buf[] = "hello"; 5113bc122d2SGleb Smirnoff char repl[sizeof(buf)]; 5123bc122d2SGleb Smirnoff const struct sockaddr_un *sun; 5133bc122d2SGleb Smirnoff int l, s, a; 5143bc122d2SGleb Smirnoff 5153bc122d2SGleb Smirnoff sun = mk_listening_socket(&l); 5163bc122d2SGleb Smirnoff 5173bc122d2SGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 5183bc122d2SGleb Smirnoff ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0); 5193bc122d2SGleb Smirnoff ATF_REQUIRE(send(s, &buf, sizeof(buf), 0) == sizeof(buf)); 5203bc122d2SGleb Smirnoff ATF_REQUIRE((a = accept(l, NULL, NULL)) != 1); 5213bc122d2SGleb Smirnoff ATF_REQUIRE(recv(a, &repl, sizeof(repl), 0) == sizeof(buf)); 5223bc122d2SGleb Smirnoff ATF_REQUIRE(strcmp(buf, repl) == 0); 5233bc122d2SGleb Smirnoff close(l); 5243bc122d2SGleb Smirnoff close(s); 5253bc122d2SGleb Smirnoff close(a); 5263bc122d2SGleb Smirnoff } 5273bc122d2SGleb Smirnoff 528f9927821SGleb Smirnoff /* 529f9927821SGleb Smirnoff * Test that close(2) of the peer ends in EPIPE when we try to send(2). 530f9927821SGleb Smirnoff * Test both normal case as well as a peer that was not accept(2)-ed. 531f9927821SGleb Smirnoff */ 532f9927821SGleb Smirnoff static bool sigpipe_received = false; 533f9927821SGleb Smirnoff static void 534f9927821SGleb Smirnoff sigpipe_handler(int signo __unused) 535f9927821SGleb Smirnoff { 536f9927821SGleb Smirnoff sigpipe_received = true; 537f9927821SGleb Smirnoff } 538f9927821SGleb Smirnoff 539f9927821SGleb Smirnoff ATF_TC_WITHOUT_HEAD(send_to_closed); 540f9927821SGleb Smirnoff ATF_TC_BODY(send_to_closed, tc) 541f9927821SGleb Smirnoff { 542f9927821SGleb Smirnoff struct sigaction sa = { 543f9927821SGleb Smirnoff .sa_handler = sigpipe_handler, 544f9927821SGleb Smirnoff }; 545f9927821SGleb Smirnoff const struct sockaddr_un *sun; 546f9927821SGleb Smirnoff int l, s, a; 547f9927821SGleb Smirnoff 548f9927821SGleb Smirnoff ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); 549f9927821SGleb Smirnoff ATF_REQUIRE(sigaction(SIGPIPE, &sa, NULL) == 0); 550f9927821SGleb Smirnoff 551f9927821SGleb Smirnoff sun = mk_listening_socket(&l); 552f9927821SGleb Smirnoff 553f9927821SGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 554f9927821SGleb Smirnoff ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0); 555f9927821SGleb Smirnoff ATF_REQUIRE((a = accept(l, NULL, NULL)) != 1); 556f9927821SGleb Smirnoff close(a); 557f9927821SGleb Smirnoff ATF_REQUIRE(send(s, &s, sizeof(s), 0) == -1); 558f9927821SGleb Smirnoff ATF_REQUIRE(errno == EPIPE); 559f9927821SGleb Smirnoff ATF_REQUIRE(sigpipe_received == true); 560f9927821SGleb Smirnoff close(s); 561f9927821SGleb Smirnoff 562f9927821SGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 563f9927821SGleb Smirnoff ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0); 564f9927821SGleb Smirnoff close(l); 565f9927821SGleb Smirnoff sigpipe_received = false; 566f9927821SGleb Smirnoff ATF_REQUIRE(send(s, &s, sizeof(s), 0) == -1); 567f9927821SGleb Smirnoff ATF_REQUIRE(errno == EPIPE); 568f9927821SGleb Smirnoff ATF_REQUIRE(sigpipe_received == true); 569f9927821SGleb Smirnoff close(s); 570f9927821SGleb Smirnoff 571f9927821SGleb Smirnoff sa.sa_handler = SIG_DFL; 572f9927821SGleb Smirnoff ATF_REQUIRE(sigaction(SIGPIPE, &sa, NULL) == 0); 573f9927821SGleb Smirnoff } 574f9927821SGleb Smirnoff 575253d8a1fSGleb Smirnoff /* Implied connect is unix/dgram only feature. Fails on stream or seqpacket. */ 576253d8a1fSGleb Smirnoff ATF_TC_WITHOUT_HEAD(implied_connect); 577253d8a1fSGleb Smirnoff ATF_TC_BODY(implied_connect, tc) 578253d8a1fSGleb Smirnoff { 579253d8a1fSGleb Smirnoff const struct sockaddr_un *sun; 580253d8a1fSGleb Smirnoff int l, s; 581253d8a1fSGleb Smirnoff 582253d8a1fSGleb Smirnoff sun = mk_listening_socket(&l); 583253d8a1fSGleb Smirnoff 584253d8a1fSGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 585253d8a1fSGleb Smirnoff ATF_REQUIRE(sendto(s, &s, sizeof(s), 0, (struct sockaddr *)sun, 586253d8a1fSGleb Smirnoff sizeof(*sun)) == -1); 587253d8a1fSGleb Smirnoff ATF_REQUIRE(errno == ENOTCONN); 588253d8a1fSGleb Smirnoff close(l); 589253d8a1fSGleb Smirnoff close(s); 590253d8a1fSGleb Smirnoff } 591253d8a1fSGleb Smirnoff 592a8eb96d5SAlan Somers /* accept(2) can receive a connection */ 593a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(accept); 594a8eb96d5SAlan Somers ATF_TC_BODY(accept, tc) 595a8eb96d5SAlan Somers { 596a8eb96d5SAlan Somers int sv[2]; 597a8eb96d5SAlan Somers 598a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 599e594026dSAlan Somers close(sv[0]); 600e594026dSAlan Somers close(sv[1]); 601a8eb96d5SAlan Somers } 602a8eb96d5SAlan Somers 603a8eb96d5SAlan Somers 604a8eb96d5SAlan Somers /* Set O_NONBLOCK on the socket */ 605a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(fcntl_nonblock); 606a8eb96d5SAlan Somers ATF_TC_BODY(fcntl_nonblock, tc) 607a8eb96d5SAlan Somers { 608a8eb96d5SAlan Somers int s; 609a8eb96d5SAlan Somers 610a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 611a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 612a8eb96d5SAlan Somers if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) { 613a8eb96d5SAlan Somers perror("fcntl"); 614a8eb96d5SAlan Somers atf_tc_fail("fcntl failed"); 615a8eb96d5SAlan Somers } 616e594026dSAlan Somers close(s); 617a8eb96d5SAlan Somers } 618a8eb96d5SAlan Somers 619a8eb96d5SAlan Somers /* Resize the send and receive buffers */ 620a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_buffers); 621a8eb96d5SAlan Somers ATF_TC_BODY(resize_buffers, tc) 622a8eb96d5SAlan Somers { 623a8eb96d5SAlan Somers int s; 624a8eb96d5SAlan Somers int sndbuf = 12345; 625a8eb96d5SAlan Somers int rcvbuf = 23456; 626a8eb96d5SAlan Somers int xs, xr; 627a8eb96d5SAlan Somers socklen_t sl = sizeof(xs); 628a8eb96d5SAlan Somers 629a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 630a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 631a8eb96d5SAlan Somers 632a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 633a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF |\n"); 634a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 635a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 636a8eb96d5SAlan Somers printf("Default | %7d | %7d |\n", xs, xr); 637a8eb96d5SAlan Somers 638a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0){ 639a8eb96d5SAlan Somers perror("setsockopt"); 640a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 641a8eb96d5SAlan Somers } 642a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 643a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 644a8eb96d5SAlan Somers printf("After changing SNDBUF | %7d | %7d |\n", xs, xr); 645a8eb96d5SAlan Somers 646a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){ 647a8eb96d5SAlan Somers perror("setsockopt"); 648a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 649a8eb96d5SAlan Somers } 650a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 651a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 652a8eb96d5SAlan Somers printf("After changing RCVBUF | %7d | %7d |\n", xs, xr); 653e594026dSAlan Somers close(s); 654a8eb96d5SAlan Somers } 655a8eb96d5SAlan Somers 656a8eb96d5SAlan Somers /* 657a8eb96d5SAlan Somers * Resize the send and receive buffers of a connected socketpair 658a8eb96d5SAlan Somers * Print some useful debugging info too 659a8eb96d5SAlan Somers */ 660a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_connected_buffers); 661a8eb96d5SAlan Somers ATF_TC_BODY(resize_connected_buffers, tc) 662a8eb96d5SAlan Somers { 663a8eb96d5SAlan Somers int sv[2]; 664a8eb96d5SAlan Somers int sndbuf = 12345; 665a8eb96d5SAlan Somers int rcvbuf = 23456; 666a8eb96d5SAlan Somers int err; 667a8eb96d5SAlan Somers int ls, lr, rs, rr; 668a8eb96d5SAlan Somers socklen_t sl = sizeof(ls); 669a8eb96d5SAlan Somers 670a8eb96d5SAlan Somers /* setup the socket pair */ 671a8eb96d5SAlan Somers do_socketpair(sv); 672a8eb96d5SAlan Somers 673a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 674a8eb96d5SAlan Somers printf(" | Left Socket | Right Socket |\n"); 675a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF | SNDBUF | RCVBUF |\n"); 676a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 677a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 678a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 679a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 680a8eb96d5SAlan Somers printf("Default | %7d | %7d | %7d | %7d |\n", 681a8eb96d5SAlan Somers ls, lr, rs, rr); 682a8eb96d5SAlan Somers 683a8eb96d5SAlan Somers /* Update one side's send buffer */ 684a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 685a8eb96d5SAlan Somers if (err != 0){ 686a8eb96d5SAlan Somers perror("setsockopt"); 687a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 688a8eb96d5SAlan Somers } 689a8eb96d5SAlan Somers 690a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 691a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 692a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 693a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 694a8eb96d5SAlan Somers printf("After changing Left's SNDBUF | %7d | %7d | %7d | %7d |\n", 695a8eb96d5SAlan Somers ls, lr, rs, rr); 696a8eb96d5SAlan Somers 697a8eb96d5SAlan Somers /* Update the same side's receive buffer */ 698a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); 699a8eb96d5SAlan Somers if (err != 0){ 700a8eb96d5SAlan Somers perror("setsockopt"); 701a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 702a8eb96d5SAlan Somers } 703a8eb96d5SAlan Somers 704a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 705a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 706a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 707a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 708a8eb96d5SAlan Somers printf("After changing Left's RCVBUF | %7d | %7d | %7d | %7d |\n", 709a8eb96d5SAlan Somers ls, lr, rs, rr); 710e594026dSAlan Somers close(sv[0]); 711e594026dSAlan Somers close(sv[1]); 712a8eb96d5SAlan Somers } 713a8eb96d5SAlan Somers 714a8eb96d5SAlan Somers 715a8eb96d5SAlan Somers /* send(2) and recv(2) a single short record */ 716a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv); 717a8eb96d5SAlan Somers ATF_TC_BODY(send_recv, tc) 718a8eb96d5SAlan Somers { 719a8eb96d5SAlan Somers int sv[2]; 720a8eb96d5SAlan Somers const int bufsize = 64; 721a8eb96d5SAlan Somers const char *data = "data"; 722a8eb96d5SAlan Somers char recv_buf[bufsize]; 7235d5b721aSAlan Somers ssize_t datalen; 724a8eb96d5SAlan Somers ssize_t ssize, rsize; 725a8eb96d5SAlan Somers 726a8eb96d5SAlan Somers /* setup the socket pair */ 727a8eb96d5SAlan Somers do_socketpair(sv); 728a8eb96d5SAlan Somers 729a8eb96d5SAlan Somers /* send and receive a small packet */ 730a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 731a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 732a8eb96d5SAlan Somers if (ssize < 0) { 733a8eb96d5SAlan Somers perror("send"); 734a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 735a8eb96d5SAlan Somers } 736a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 737a8eb96d5SAlan Somers datalen, ssize); 738a8eb96d5SAlan Somers 739a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 740a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 741e594026dSAlan Somers close(sv[0]); 742e594026dSAlan Somers close(sv[1]); 743a8eb96d5SAlan Somers } 744a8eb96d5SAlan Somers 745a8eb96d5SAlan Somers /* sendto(2) and recvfrom(2) a single short record 746a8eb96d5SAlan Somers * According to The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 747a8eb96d5SAlan Somers * Edition, sendto(2) is exactly the same as send(2) on a connection-mode socket 748a8eb96d5SAlan Somers * 749a8eb96d5SAlan Somers * According to the same spec, not all protocols are required to provide the 750a8eb96d5SAlan Somers * source addres in recvfrom(2). 751a8eb96d5SAlan Somers */ 752a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendto_recvfrom); 753a8eb96d5SAlan Somers ATF_TC_BODY(sendto_recvfrom, tc) 754a8eb96d5SAlan Somers { 755983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 7561f46c32cSGleb Smirnoff const sockaddr_un *sun; 757983a2d91SEnji Cooper #endif 758a8eb96d5SAlan Somers struct sockaddr_storage from; 759a8eb96d5SAlan Somers int sv[2]; 760a8eb96d5SAlan Somers const int bufsize = 64; 761a8eb96d5SAlan Somers const char *data = "data"; 762a8eb96d5SAlan Somers char recv_buf[bufsize]; 7635d5b721aSAlan Somers ssize_t datalen; 764a8eb96d5SAlan Somers ssize_t ssize, rsize; 765a8eb96d5SAlan Somers socklen_t fromlen; 766a8eb96d5SAlan Somers 767a8eb96d5SAlan Somers /* setup the socket pair */ 768983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 7691f46c32cSGleb Smirnoff sun = 770983a2d91SEnji Cooper #endif 771983a2d91SEnji Cooper mk_pair_of_sockets(sv); 772a8eb96d5SAlan Somers 773a8eb96d5SAlan Somers /* send and receive a small packet */ 774a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 775a8eb96d5SAlan Somers ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0); 776a8eb96d5SAlan Somers if (ssize < 0) { 777a8eb96d5SAlan Somers perror("send"); 778a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 779a8eb96d5SAlan Somers } 780a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 781a8eb96d5SAlan Somers datalen, ssize); 782a8eb96d5SAlan Somers 783a8eb96d5SAlan Somers fromlen = sizeof(from); 784a8eb96d5SAlan Somers rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL, 785a8eb96d5SAlan Somers (struct sockaddr*)&from, &fromlen); 786a8eb96d5SAlan Somers if (ssize < 0) { 787a8eb96d5SAlan Somers perror("recvfrom"); 788a8eb96d5SAlan Somers atf_tc_fail("recvfrom returned < 0"); 789a8eb96d5SAlan Somers } 790a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 791a8eb96d5SAlan Somers 792983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 793a8eb96d5SAlan Somers /* 794a8eb96d5SAlan Somers * FreeBSD does not currently provide the source address for SEQ_PACKET 795a8eb96d5SAlan Somers * AF_UNIX sockets, and POSIX does not require it, so these two checks 796a8eb96d5SAlan Somers * are disabled. If FreeBSD gains that feature in the future, then 797a8eb96d5SAlan Somers * these checks may be reenabled 798a8eb96d5SAlan Somers */ 799983a2d91SEnji Cooper ATF_CHECK_EQ(PF_LOCAL, from.ss_family); 8001f46c32cSGleb Smirnoff ATF_CHECK_STREQ(sun->sun_path, ((struct sockaddr_un*)&from)->sun_path); 801983a2d91SEnji Cooper #endif 802e594026dSAlan Somers close(sv[0]); 803e594026dSAlan Somers close(sv[1]); 804a8eb96d5SAlan Somers } 805a8eb96d5SAlan Somers 806a8eb96d5SAlan Somers /* 807a8eb96d5SAlan Somers * send(2) and recv(2) a single short record with sockets created the 808a8eb96d5SAlan Somers * traditional way, involving bind, listen, connect, and accept 809a8eb96d5SAlan Somers */ 810a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_with_connect); 811a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_with_connect, tc) 812a8eb96d5SAlan Somers { 813a8eb96d5SAlan Somers int sv[2]; 814a8eb96d5SAlan Somers const int bufsize = 64; 815a8eb96d5SAlan Somers const char *data = "data"; 816a8eb96d5SAlan Somers char recv_buf[bufsize]; 8175d5b721aSAlan Somers ssize_t datalen; 818a8eb96d5SAlan Somers ssize_t ssize, rsize; 819a8eb96d5SAlan Somers 820a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 821a8eb96d5SAlan Somers 822a8eb96d5SAlan Somers /* send and receive a small packet */ 823a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 824a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 825a8eb96d5SAlan Somers if (ssize < 0) { 826a8eb96d5SAlan Somers perror("send"); 827a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 828a8eb96d5SAlan Somers } 829a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 830a8eb96d5SAlan Somers datalen, ssize); 831a8eb96d5SAlan Somers 832a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 833a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 834e594026dSAlan Somers close(sv[0]); 835e594026dSAlan Somers close(sv[1]); 836a8eb96d5SAlan Somers } 837a8eb96d5SAlan Somers 838a8eb96d5SAlan Somers /* send(2) should fail on a shutdown socket */ 839a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send); 840a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send, tc) 841a8eb96d5SAlan Somers { 8421f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 8434446a47aSSergey Kandaurov const char *data = "data"; 844fa5e5f53SEnji Cooper ssize_t datalen, ssize; 8454446a47aSSergey Kandaurov int s, err, s2; 846a8eb96d5SAlan Somers 8471f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 8484446a47aSSergey Kandaurov 8494446a47aSSergey Kandaurov /* Create the other socket */ 8504446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 8514446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 8521f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 8534446a47aSSergey Kandaurov if (err != 0) { 8544446a47aSSergey Kandaurov perror("connect"); 8554446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 8564446a47aSSergey Kandaurov } 8574446a47aSSergey Kandaurov 8584446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 859fa5e5f53SEnji Cooper datalen = strlen(data) + 1; /* +1 for the null */ 860a8eb96d5SAlan Somers /* USE MSG_NOSIGNAL so we don't get SIGPIPE */ 861fa5e5f53SEnji Cooper ssize = send(s2, data, datalen, MSG_EOR | MSG_NOSIGNAL); 862a8eb96d5SAlan Somers ATF_CHECK_EQ(EPIPE, errno); 863a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 864e594026dSAlan Somers close(s); 8654446a47aSSergey Kandaurov close(s2); 866a8eb96d5SAlan Somers } 867a8eb96d5SAlan Somers 868a8eb96d5SAlan Somers /* send(2) should cause SIGPIPE on a shutdown socket */ 869a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe); 870a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send_sigpipe, tc) 871a8eb96d5SAlan Somers { 8721f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 8734446a47aSSergey Kandaurov const char *data = "data"; 874fa5e5f53SEnji Cooper ssize_t datalen; 8754446a47aSSergey Kandaurov int s, err, s2; 876a8eb96d5SAlan Somers 8771f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 8784446a47aSSergey Kandaurov 8794446a47aSSergey Kandaurov /* Create the other socket */ 8804446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 8814446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 8821f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 8834446a47aSSergey Kandaurov if (err != 0) { 8844446a47aSSergey Kandaurov perror("connect"); 8854446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 8864446a47aSSergey Kandaurov } 8874446a47aSSergey Kandaurov 8884446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 889a8eb96d5SAlan Somers ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); 890fa5e5f53SEnji Cooper datalen = strlen(data) + 1; /* +1 for the null */ 8916dd202ceSJohn Baldwin (void)send(s2, data, datalen, MSG_EOR); 892a8eb96d5SAlan Somers ATF_CHECK_EQ(1, got_sigpipe); 893e594026dSAlan Somers close(s); 8944446a47aSSergey Kandaurov close(s2); 895a8eb96d5SAlan Somers } 896a8eb96d5SAlan Somers 897a8eb96d5SAlan Somers /* nonblocking send(2) and recv(2) a single short record */ 898a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 899a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_nonblocking, tc) 900a8eb96d5SAlan Somers { 901a8eb96d5SAlan Somers int sv[2]; 902a8eb96d5SAlan Somers const int bufsize = 64; 903a8eb96d5SAlan Somers const char *data = "data"; 904a8eb96d5SAlan Somers char recv_buf[bufsize]; 9055d5b721aSAlan Somers ssize_t datalen; 906a8eb96d5SAlan Somers ssize_t ssize, rsize; 907a8eb96d5SAlan Somers 908a8eb96d5SAlan Somers /* setup the socket pair */ 909a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 910a8eb96d5SAlan Somers 911a8eb96d5SAlan Somers /* Verify that there is nothing to receive */ 912a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 913a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 914a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 915a8eb96d5SAlan Somers 916a8eb96d5SAlan Somers /* send and receive a small packet */ 917a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 918a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 919a8eb96d5SAlan Somers if (ssize < 0) { 920a8eb96d5SAlan Somers perror("send"); 921a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 922a8eb96d5SAlan Somers } 923a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 924a8eb96d5SAlan Somers datalen, ssize); 925a8eb96d5SAlan Somers 926a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 927a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 928e594026dSAlan Somers close(sv[0]); 929e594026dSAlan Somers close(sv[1]); 930a8eb96d5SAlan Somers } 931a8eb96d5SAlan Somers 932a8eb96d5SAlan Somers /* 933a8eb96d5SAlan Somers * We should get EAGAIN if we try to send a message larger than the socket 934a8eb96d5SAlan Somers * buffer, with nonblocking sockets. Test with several different sockbuf sizes 935a8eb96d5SAlan Somers */ 936a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_8k); 937a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_8k, tc) 938a8eb96d5SAlan Somers { 939a8eb96d5SAlan Somers test_eagain(8192, 8192); 940a8eb96d5SAlan Somers } 941a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_128k); 942a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_128k, tc) 943a8eb96d5SAlan Somers { 944a8eb96d5SAlan Somers test_eagain(8192, 131072); 945a8eb96d5SAlan Somers } 946a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_8k); 947a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_8k, tc) 948a8eb96d5SAlan Somers { 949a8eb96d5SAlan Somers test_eagain(131072, 8192); 950a8eb96d5SAlan Somers } 951a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_128k); 952a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_128k, tc) 953a8eb96d5SAlan Somers { 954a8eb96d5SAlan Somers test_eagain(131072, 131072); 955a8eb96d5SAlan Somers } 956a8eb96d5SAlan Somers 957a8eb96d5SAlan Somers 958a8eb96d5SAlan Somers /* 959a8eb96d5SAlan Somers * nonblocking send(2) and recv(2) of several records, which should collectively 960a8eb96d5SAlan Somers * fill up the send buffer but not the receive buffer 961a8eb96d5SAlan Somers */ 962a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(rcvbuf_oversized); 963a8eb96d5SAlan Somers ATF_TC_BODY(rcvbuf_oversized, tc) 964a8eb96d5SAlan Somers { 9655d5b721aSAlan Somers int i; 966a8eb96d5SAlan Somers int sv[2]; 9673be7751dSJulio Merino const ssize_t pktsize = 1024; 968ea703329SBrooks Davis const int sndbufsize = 8192; 969ea703329SBrooks Davis const int rcvbufsize = 131072; 9705d5b721aSAlan Somers const size_t geometric_mean_bufsize = 32768; 9715d5b721aSAlan Somers const int numpkts = geometric_mean_bufsize / pktsize; 972a8eb96d5SAlan Somers char sndbuf[pktsize]; 973a8eb96d5SAlan Somers char recv_buf[pktsize]; 974a8eb96d5SAlan Somers ssize_t ssize, rsize; 975a8eb96d5SAlan Somers 976a8eb96d5SAlan Somers /* setup the socket pair */ 977a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 9785d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 9795d5b721aSAlan Somers sizeof(sndbufsize))); 9805d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 9815d5b721aSAlan Somers sizeof(rcvbufsize))); 982a8eb96d5SAlan Somers 983a8eb96d5SAlan Somers /* 984a8eb96d5SAlan Somers * Send and receive packets that are collectively greater than the send 985a8eb96d5SAlan Somers * buffer, but less than the receive buffer 986a8eb96d5SAlan Somers */ 9875d5b721aSAlan Somers for (i=0; i < numpkts; i++) { 988a8eb96d5SAlan Somers /* Fill the buffer */ 989a8eb96d5SAlan Somers memset(sndbuf, i, pktsize); 990a8eb96d5SAlan Somers 991a8eb96d5SAlan Somers /* send the packet */ 992a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 993a8eb96d5SAlan Somers if (ssize < 0) { 994a8eb96d5SAlan Somers perror("send"); 995a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 996a8eb96d5SAlan Somers } 997a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 998a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, ssize); 999a8eb96d5SAlan Somers 1000a8eb96d5SAlan Somers /* Receive it */ 1001a8eb96d5SAlan Somers 1002a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 1003a8eb96d5SAlan Somers if (rsize < 0) { 1004a8eb96d5SAlan Somers perror("recv"); 1005a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 1006a8eb96d5SAlan Somers } 1007a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 1008a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, rsize); 1009a8eb96d5SAlan Somers 1010a8eb96d5SAlan Somers /* Verify the contents */ 1011a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), 1012a8eb96d5SAlan Somers "Received data miscompare"); 1013a8eb96d5SAlan Somers } 1014a8eb96d5SAlan Somers 1015a8eb96d5SAlan Somers /* Trying to receive again should return EAGAIN */ 1016a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 1017a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 1018a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 1019e594026dSAlan Somers close(sv[0]); 1020e594026dSAlan Somers close(sv[1]); 1021a8eb96d5SAlan Somers } 1022a8eb96d5SAlan Somers 1023a8eb96d5SAlan Somers /* 1024a8eb96d5SAlan Somers * Simulate the behavior of a blocking pipe. The sender will send until his 1025a8eb96d5SAlan Somers * buffer fills up, then we'll simulate a scheduler switch that will allow the 1026a8eb96d5SAlan Somers * receiver to read until his buffer empties. Repeat the process until the 1027a8eb96d5SAlan Somers * transfer is complete. 1028a8eb96d5SAlan Somers * Repeat the test with multiple send and receive buffer sizes 1029a8eb96d5SAlan Somers */ 1030a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k); 1031a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_8k, tc) 1032a8eb96d5SAlan Somers { 1033a8eb96d5SAlan Somers test_pipe_simulator(8192, 8192); 1034a8eb96d5SAlan Somers } 1035a8eb96d5SAlan Somers 1036a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k); 1037a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_128k, tc) 1038a8eb96d5SAlan Somers { 1039a8eb96d5SAlan Somers test_pipe_simulator(8192, 131072); 1040a8eb96d5SAlan Somers } 1041a8eb96d5SAlan Somers 1042a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k); 1043a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_8k, tc) 1044a8eb96d5SAlan Somers { 1045a8eb96d5SAlan Somers test_pipe_simulator(131072, 8192); 1046a8eb96d5SAlan Somers } 1047a8eb96d5SAlan Somers 1048a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k); 1049a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_128k, tc) 1050a8eb96d5SAlan Somers { 1051a8eb96d5SAlan Somers test_pipe_simulator(131072, 131072); 1052a8eb96d5SAlan Somers } 1053a8eb96d5SAlan Somers 1054a8eb96d5SAlan Somers /* 1055a8eb96d5SAlan Somers * Test blocking I/O by passing data between two threads. The total amount of 1056a8eb96d5SAlan Somers * data will be >> buffer size to force blocking. Repeat the test with multiple 1057a8eb96d5SAlan Somers * send and receive buffer sizes 1058a8eb96d5SAlan Somers */ 1059a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_8k); 1060a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_8k, tc) 1061a8eb96d5SAlan Somers { 1062a8eb96d5SAlan Somers test_pipe(8192, 8192); 1063a8eb96d5SAlan Somers } 1064a8eb96d5SAlan Somers 1065a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_128k); 1066a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_128k, tc) 1067a8eb96d5SAlan Somers { 1068a8eb96d5SAlan Somers test_pipe(8192, 131072); 1069a8eb96d5SAlan Somers } 1070a8eb96d5SAlan Somers 1071a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_8k); 1072a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_8k, tc) 1073a8eb96d5SAlan Somers { 1074a8eb96d5SAlan Somers test_pipe(131072, 8192); 1075a8eb96d5SAlan Somers } 1076a8eb96d5SAlan Somers 1077a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_128k); 1078a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_128k, tc) 1079a8eb96d5SAlan Somers { 1080a8eb96d5SAlan Somers test_pipe(131072, 131072); 1081a8eb96d5SAlan Somers } 1082a8eb96d5SAlan Somers 1083a8eb96d5SAlan Somers 1084a8eb96d5SAlan Somers /* 1085a8eb96d5SAlan Somers * Test single-packet I/O with and without blocking, with symmetric buffers of 1086a8eb96d5SAlan Somers * various sizes 1087a8eb96d5SAlan Somers */ 1088a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k); 1089a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k, tc) 1090a8eb96d5SAlan Somers { 1091a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, true); 1092a8eb96d5SAlan Somers } 1093a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k); 1094a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k, tc) 1095a8eb96d5SAlan Somers { 1096a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, true); 1097a8eb96d5SAlan Somers } 1098a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k); 1099a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k, tc) 1100a8eb96d5SAlan Somers { 1101a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, true); 1102a8eb96d5SAlan Somers } 1103a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k); 1104a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k, tc) 1105a8eb96d5SAlan Somers { 1106a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, true); 1107a8eb96d5SAlan Somers } 1108a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k); 1109a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k, tc) 1110a8eb96d5SAlan Somers { 1111a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, true); 1112a8eb96d5SAlan Somers } 1113a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking); 1114a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k_nonblocking, tc) 1115a8eb96d5SAlan Somers { 1116a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, false); 1117a8eb96d5SAlan Somers } 1118a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking); 1119a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k_nonblocking, tc) 1120a8eb96d5SAlan Somers { 1121a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, false); 1122a8eb96d5SAlan Somers } 1123a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking); 1124a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k_nonblocking, tc) 1125a8eb96d5SAlan Somers { 1126a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, false); 1127a8eb96d5SAlan Somers } 1128a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking); 1129a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k_nonblocking, tc) 1130a8eb96d5SAlan Somers { 1131a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, false); 1132a8eb96d5SAlan Somers } 1133a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking); 1134a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k_nonblocking, tc) 1135a8eb96d5SAlan Somers { 1136a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, false); 1137a8eb96d5SAlan Somers } 1138a8eb96d5SAlan Somers 1139eb338e23SGleb Smirnoff ATF_TC(random_eor_and_waitall); 1140eb338e23SGleb Smirnoff ATF_TC_HEAD(random_eor_and_waitall, tc) 1141eb338e23SGleb Smirnoff { 1142eb338e23SGleb Smirnoff atf_tc_set_md_var(tc, "descr", "Test random sized send/recv with " 1143eb338e23SGleb Smirnoff "randomly placed MSG_EOR and randomly applied MSG_WAITALL on " 1144eb338e23SGleb Smirnoff "PF_UNIX/SOCK_SEQPACKET"); 1145eb338e23SGleb Smirnoff } 1146eb338e23SGleb Smirnoff 1147eb338e23SGleb Smirnoff struct random_eor_params { 1148eb338e23SGleb Smirnoff u_long recvspace; 1149eb338e23SGleb Smirnoff char *sendbuf; 1150eb338e23SGleb Smirnoff size_t *records; 1151eb338e23SGleb Smirnoff u_int nrecords; 1152eb338e23SGleb Smirnoff int sock; 1153eb338e23SGleb Smirnoff u_short seed[6]; 1154eb338e23SGleb Smirnoff }; 1155eb338e23SGleb Smirnoff 1156eb338e23SGleb Smirnoff #define RANDOM_TESTSIZE ((size_t)100 * 1024 * 1024) 1157eb338e23SGleb Smirnoff /* Below defines are factor of recvspace. */ 1158eb338e23SGleb Smirnoff #define RANDOM_MAXRECORD 10 1159eb338e23SGleb Smirnoff #define RANDOM_SENDSIZE 2 1160eb338e23SGleb Smirnoff #define RANDOM_RECVSIZE 4 1161eb338e23SGleb Smirnoff 1162eb338e23SGleb Smirnoff static void * 1163eb338e23SGleb Smirnoff sending_thread(void *arg) 1164eb338e23SGleb Smirnoff { 1165eb338e23SGleb Smirnoff struct random_eor_params *params = arg; 1166eb338e23SGleb Smirnoff size_t off = 0; 1167eb338e23SGleb Smirnoff int eor = 0; 1168eb338e23SGleb Smirnoff 1169eb338e23SGleb Smirnoff while (off < RANDOM_TESTSIZE) { 1170eb338e23SGleb Smirnoff ssize_t len; 1171eb338e23SGleb Smirnoff int flags; 1172eb338e23SGleb Smirnoff 1173eb338e23SGleb Smirnoff len = nrand48(¶ms->seed[3]) % 1174eb338e23SGleb Smirnoff (RANDOM_SENDSIZE * params->recvspace); 1175eb338e23SGleb Smirnoff if (off + len >= params->records[eor]) { 1176eb338e23SGleb Smirnoff len = params->records[eor] - off; 1177eb338e23SGleb Smirnoff flags = MSG_EOR; 1178eb338e23SGleb Smirnoff eor++; 1179eb338e23SGleb Smirnoff } else 1180eb338e23SGleb Smirnoff flags = 0; 1181eb338e23SGleb Smirnoff ATF_REQUIRE(send(params->sock, ¶ms->sendbuf[off], len, 1182eb338e23SGleb Smirnoff flags) == len); 1183eb338e23SGleb Smirnoff off += len; 1184eb338e23SGleb Smirnoff #ifdef DEBUG 1185eb338e23SGleb Smirnoff printf("send %zd%s\n", off, flags ? " EOR" : ""); 1186eb338e23SGleb Smirnoff #endif 1187eb338e23SGleb Smirnoff } 1188eb338e23SGleb Smirnoff 1189eb338e23SGleb Smirnoff return (NULL); 1190eb338e23SGleb Smirnoff } 1191eb338e23SGleb Smirnoff 1192eb338e23SGleb Smirnoff ATF_TC_BODY(random_eor_and_waitall, tc) 1193eb338e23SGleb Smirnoff { 1194eb338e23SGleb Smirnoff struct random_eor_params params; 1195eb338e23SGleb Smirnoff void *recvbuf; 1196eb338e23SGleb Smirnoff pthread_t t; 1197eb338e23SGleb Smirnoff size_t off; 1198eb338e23SGleb Smirnoff int fd[2], eor; 1199eb338e23SGleb Smirnoff 1200b2351a4bSWarner Losh if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false)) 1201*0c00c3d7SWarner Losh atf_tc_skip("https://bugs.freebsd.org/279354"); 1202b2351a4bSWarner Losh 1203eb338e23SGleb Smirnoff arc4random_buf(params.seed, sizeof(params.seed)); 1204eb338e23SGleb Smirnoff printf("Using seed:"); 1205eb338e23SGleb Smirnoff for (u_int i = 0; i < (u_int)sizeof(params.seed)/sizeof(u_short); i++) 1206eb338e23SGleb Smirnoff printf(" 0x%.4x,", params.seed[i]); 1207eb338e23SGleb Smirnoff printf("\n"); 1208eb338e23SGleb Smirnoff 1209eb338e23SGleb Smirnoff ATF_REQUIRE((params.sendbuf = malloc(RANDOM_TESTSIZE)) != NULL); 1210eb338e23SGleb Smirnoff for (u_int i = 0; i < RANDOM_TESTSIZE / (u_int )sizeof(long); i++) 1211eb338e23SGleb Smirnoff ((long *)params.sendbuf)[i] = nrand48(¶ms.seed[0]); 1212eb338e23SGleb Smirnoff 1213eb338e23SGleb Smirnoff ATF_REQUIRE(sysctlbyname("net.local.stream.recvspace", 1214eb338e23SGleb Smirnoff ¶ms.recvspace, &(size_t){sizeof(u_long)}, NULL, 0) != -1); 1215eb338e23SGleb Smirnoff ATF_REQUIRE((recvbuf = 1216eb338e23SGleb Smirnoff malloc(RANDOM_RECVSIZE * params.recvspace)) != NULL); 1217eb338e23SGleb Smirnoff 1218eb338e23SGleb Smirnoff params.nrecords = 2 * RANDOM_TESTSIZE / 1219eb338e23SGleb Smirnoff (RANDOM_MAXRECORD * params.recvspace); 1220eb338e23SGleb Smirnoff 1221eb338e23SGleb Smirnoff ATF_REQUIRE((params.records = 1222eb338e23SGleb Smirnoff malloc(params.nrecords * sizeof(size_t *))) != NULL); 1223eb338e23SGleb Smirnoff off = 0; 1224eb338e23SGleb Smirnoff for (u_int i = 0; i < params.nrecords; i++) { 1225eb338e23SGleb Smirnoff off += 1 + nrand48(¶ms.seed[0]) % 1226eb338e23SGleb Smirnoff (RANDOM_MAXRECORD * params.recvspace); 1227eb338e23SGleb Smirnoff if (off > RANDOM_TESTSIZE) { 1228eb338e23SGleb Smirnoff params.nrecords = i; 1229eb338e23SGleb Smirnoff break; 1230eb338e23SGleb Smirnoff } 1231eb338e23SGleb Smirnoff params.records[i] = off; 1232eb338e23SGleb Smirnoff } 1233eb338e23SGleb Smirnoff params.records[params.nrecords - 1] = RANDOM_TESTSIZE; 1234eb338e23SGleb Smirnoff 1235eb338e23SGleb Smirnoff ATF_REQUIRE(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, fd) == 0); 1236eb338e23SGleb Smirnoff params.sock = fd[0]; 1237eb338e23SGleb Smirnoff ATF_REQUIRE(pthread_create(&t, NULL, sending_thread, ¶ms) == 0); 1238eb338e23SGleb Smirnoff 1239eb338e23SGleb Smirnoff off = 0; 1240eb338e23SGleb Smirnoff eor = 0; 1241eb338e23SGleb Smirnoff while (off < RANDOM_TESTSIZE) { 1242eb338e23SGleb Smirnoff struct iovec iov = { 1243eb338e23SGleb Smirnoff .iov_base = recvbuf, 1244eb338e23SGleb Smirnoff .iov_len = nrand48(¶ms.seed[0]) % 1245eb338e23SGleb Smirnoff (RANDOM_RECVSIZE * params.recvspace) 1246eb338e23SGleb Smirnoff }; 1247eb338e23SGleb Smirnoff struct msghdr hdr = { 1248eb338e23SGleb Smirnoff .msg_iov = &iov, 1249eb338e23SGleb Smirnoff .msg_iovlen = 1, 1250eb338e23SGleb Smirnoff }; 1251eb338e23SGleb Smirnoff size_t len; 1252eb338e23SGleb Smirnoff int waitall = iov.iov_len & 0x1 ? MSG_WAITALL : 0; 1253eb338e23SGleb Smirnoff 1254eb338e23SGleb Smirnoff len = recvmsg(fd[1], &hdr, waitall); 1255eb338e23SGleb Smirnoff if (waitall && !(hdr.msg_flags & MSG_EOR)) 1256eb338e23SGleb Smirnoff ATF_CHECK_EQ_MSG(len, iov.iov_len, 1257eb338e23SGleb Smirnoff "recvmsg(MSG_WAITALL): %zd, expected %zd", 1258eb338e23SGleb Smirnoff len, iov.iov_len); 1259eb338e23SGleb Smirnoff if (off + len == params.records[eor]) { 1260eb338e23SGleb Smirnoff ATF_REQUIRE_MSG(hdr.msg_flags & MSG_EOR, 1261eb338e23SGleb Smirnoff "recvmsg(): expected EOR @ %zd", off + len); 1262eb338e23SGleb Smirnoff eor++; 1263eb338e23SGleb Smirnoff } else { 1264eb338e23SGleb Smirnoff ATF_REQUIRE_MSG(off + len < params.records[eor], 1265eb338e23SGleb Smirnoff "recvmsg() past EOR: %zd, expected %zd", 1266eb338e23SGleb Smirnoff off + len, params.records[eor]); 1267eb338e23SGleb Smirnoff ATF_REQUIRE_MSG(!(hdr.msg_flags & MSG_EOR), 1268eb338e23SGleb Smirnoff "recvmsg() spurious EOR at %zd, expected %zd", 1269eb338e23SGleb Smirnoff off + len, params.records[eor]); 1270eb338e23SGleb Smirnoff } 1271eb338e23SGleb Smirnoff ATF_REQUIRE_MSG(0 == memcmp(params.sendbuf + off, recvbuf, len), 1272eb338e23SGleb Smirnoff "data corruption past %zd", off); 1273eb338e23SGleb Smirnoff off += len; 1274eb338e23SGleb Smirnoff #ifdef DEBUG 1275eb338e23SGleb Smirnoff printf("recv %zd%s %zd/%zd%s\n", off, 1276eb338e23SGleb Smirnoff (hdr.msg_flags & MSG_EOR) ? " EOR" : "", 1277eb338e23SGleb Smirnoff len, iov.iov_len, 1278eb338e23SGleb Smirnoff waitall ? " WAITALL" : ""); 1279eb338e23SGleb Smirnoff #endif 1280eb338e23SGleb Smirnoff } 1281eb338e23SGleb Smirnoff 1282eb338e23SGleb Smirnoff ATF_REQUIRE(pthread_join(t, NULL) == 0); 1283eb338e23SGleb Smirnoff free(params.sendbuf); 1284eb338e23SGleb Smirnoff free(recvbuf); 1285eb338e23SGleb Smirnoff free(params.records); 1286eb338e23SGleb Smirnoff } 1287a8eb96d5SAlan Somers 1288a8eb96d5SAlan Somers /* 1289a8eb96d5SAlan Somers * Main. 1290a8eb96d5SAlan Somers */ 1291a8eb96d5SAlan Somers 1292a8eb96d5SAlan Somers ATF_TP_ADD_TCS(tp) 1293a8eb96d5SAlan Somers { 1294a8eb96d5SAlan Somers /* Basic creation and connection tests */ 1295a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socket); 1296a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socketpair); 1297a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_unbound); 1298a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, bind); 1299a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_bound); 1300a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, connect); 1301a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, accept); 1302a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, fcntl_nonblock); 1303a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_buffers); 1304a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_connected_buffers); 1305a8eb96d5SAlan Somers 1306a8eb96d5SAlan Somers /* Unthreaded I/O tests */ 1307a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv); 1308a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_nonblocking); 1309a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_with_connect); 1310a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendto_recvfrom); 13113bc122d2SGleb Smirnoff ATF_TP_ADD_TC(tp, send_before_accept); 1312f9927821SGleb Smirnoff ATF_TP_ADD_TC(tp, send_to_closed); 1313253d8a1fSGleb Smirnoff ATF_TP_ADD_TC(tp, implied_connect); 1314a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send); 1315a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send_sigpipe); 1316a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_8k); 1317a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_128k); 1318a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_8k); 1319a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_128k); 1320a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k); 1321a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k); 1322a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k); 1323a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k); 1324a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k); 1325a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking); 1326a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking); 1327a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking); 1328a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking); 1329a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking); 1330a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, rcvbuf_oversized); 1331a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k); 1332a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k); 1333a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k); 1334a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k); 1335a8eb96d5SAlan Somers 1336a8eb96d5SAlan Somers /* Threaded I/O tests with blocking sockets */ 1337a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_8k); 1338a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_128k); 1339a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_8k); 1340a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_128k); 1341eb338e23SGleb Smirnoff ATF_TP_ADD_TC(tp, random_eor_and_waitall); 1342a8eb96d5SAlan Somers 1343a8eb96d5SAlan Somers return atf_no_error(); 1344a8eb96d5SAlan Somers } 1345