1a8eb96d5SAlan Somers /*- 2a8eb96d5SAlan Somers * Copyright (c) 2014 Spectra Logic Corporation. All rights reserved. 3a8eb96d5SAlan Somers * Redistribution and use in source and binary forms, with or without 4a8eb96d5SAlan Somers * modification, are permitted provided that the following conditions 5a8eb96d5SAlan Somers * are met: 6a8eb96d5SAlan Somers * 1. Redistributions of source code must retain the above copyright 7a8eb96d5SAlan Somers * notice, this list of conditions and the following disclaimer. 8a8eb96d5SAlan Somers * 2. Redistributions in binary form must reproduce the above copyright 9a8eb96d5SAlan Somers * notice, this list of conditions and the following disclaimer in the 10a8eb96d5SAlan Somers * documentation and/or other materials provided with the distribution. 11a8eb96d5SAlan Somers * 12a8eb96d5SAlan Somers * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 13a8eb96d5SAlan Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14a8eb96d5SAlan Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15a8eb96d5SAlan Somers * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 16a8eb96d5SAlan Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17a8eb96d5SAlan Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 18a8eb96d5SAlan Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 19a8eb96d5SAlan Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 20a8eb96d5SAlan Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21a8eb96d5SAlan Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 22a8eb96d5SAlan Somers * SUCH DAMAGE. 23a8eb96d5SAlan Somers */ 24a8eb96d5SAlan Somers 25a8eb96d5SAlan Somers #include <sys/cdefs.h> 26a8eb96d5SAlan Somers #include <errno.h> 27a8eb96d5SAlan Somers #include <fcntl.h> 28a8eb96d5SAlan Somers #include <pthread.h> 29a8eb96d5SAlan Somers #include <signal.h> 30a8eb96d5SAlan Somers #include <sys/socket.h> 31a8eb96d5SAlan Somers #include <sys/un.h> 32a8eb96d5SAlan Somers 33a8eb96d5SAlan Somers #include <stdio.h> 34a8eb96d5SAlan Somers 35a8eb96d5SAlan Somers #include <atf-c.h> 36a8eb96d5SAlan Somers 37a8eb96d5SAlan Somers /* 38a8eb96d5SAlan Somers * Helper functions 39a8eb96d5SAlan Somers */ 40a8eb96d5SAlan Somers 41a8eb96d5SAlan Somers #define MIN(x, y) ((x) < (y) ? (x) : (y)) 42a8eb96d5SAlan Somers #define MAX(x, y) ((x) > (y) ? (x) : (y)) 43a8eb96d5SAlan Somers 445d5b721aSAlan Somers static void 45a8eb96d5SAlan Somers do_socketpair(int *sv) 46a8eb96d5SAlan Somers { 47a8eb96d5SAlan Somers int s; 48a8eb96d5SAlan Somers 49a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 50a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 51a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] >= 0); 52a8eb96d5SAlan Somers ATF_REQUIRE(sv[1] >= 0); 53a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] != sv[1]); 54a8eb96d5SAlan Somers } 55a8eb96d5SAlan Somers 565d5b721aSAlan Somers static void 57a8eb96d5SAlan Somers do_socketpair_nonblocking(int *sv) 58a8eb96d5SAlan Somers { 59a8eb96d5SAlan Somers int s; 60a8eb96d5SAlan Somers 61a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 62a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 63a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] >= 0); 64a8eb96d5SAlan Somers ATF_REQUIRE(sv[1] >= 0); 65a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] != sv[1]); 66a8eb96d5SAlan Somers ATF_REQUIRE(-1 != fcntl(sv[0], F_SETFL, O_NONBLOCK)); 67a8eb96d5SAlan Somers ATF_REQUIRE(-1 != fcntl(sv[1], F_SETFL, O_NONBLOCK)); 68a8eb96d5SAlan Somers } 69a8eb96d5SAlan Somers 70a8eb96d5SAlan Somers /* 711f46c32cSGleb Smirnoff * Returns a bound and listening socket. 72a8eb96d5SAlan Somers * @return const char* The path to the socket 73a8eb96d5SAlan Somers */ 741f46c32cSGleb Smirnoff static const struct sockaddr_un * 751f46c32cSGleb Smirnoff mk_listening_socket(int *sv) 76a8eb96d5SAlan Somers { 77a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 781f46c32cSGleb Smirnoff static const struct sockaddr_un sun = { 791f46c32cSGleb Smirnoff .sun_family = AF_LOCAL, 801f46c32cSGleb Smirnoff .sun_len = sizeof(sun), 811f46c32cSGleb Smirnoff .sun_path = "sock", 821f46c32cSGleb Smirnoff }; 831f46c32cSGleb Smirnoff int s, r, l; 84a8eb96d5SAlan Somers 85a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 86a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 87a8eb96d5SAlan Somers 881f46c32cSGleb Smirnoff r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 891f46c32cSGleb Smirnoff l = listen(s, -1); 901f46c32cSGleb Smirnoff ATF_CHECK_EQ(0, r); 911f46c32cSGleb Smirnoff ATF_CHECK_EQ(0, l); 921f46c32cSGleb Smirnoff 931f46c32cSGleb Smirnoff if (sv != NULL) 941f46c32cSGleb Smirnoff *sv = s; 951f46c32cSGleb Smirnoff 961f46c32cSGleb Smirnoff return (&sun); 971f46c32cSGleb Smirnoff } 981f46c32cSGleb Smirnoff 991f46c32cSGleb Smirnoff /* 1001f46c32cSGleb Smirnoff * Returns a pair of sockets made the hard way: bind, listen, connect & accept 1011f46c32cSGleb Smirnoff * @return const char* The path to the socket 1021f46c32cSGleb Smirnoff */ 1031f46c32cSGleb Smirnoff static const struct sockaddr_un * 1041f46c32cSGleb Smirnoff mk_pair_of_sockets(int *sv) 1051f46c32cSGleb Smirnoff { 1061f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 1071f46c32cSGleb Smirnoff int s, s2, err, s1; 1081f46c32cSGleb Smirnoff 1091f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 110a8eb96d5SAlan Somers 111a8eb96d5SAlan Somers /* Create the other socket */ 112a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 113a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 1141f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 115a8eb96d5SAlan Somers if (err != 0) { 116a8eb96d5SAlan Somers perror("connect"); 117a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 118a8eb96d5SAlan Somers } 119a8eb96d5SAlan Somers 120a8eb96d5SAlan Somers /* Accept it */ 121a8eb96d5SAlan Somers s1 = accept(s, NULL, NULL); 122a8eb96d5SAlan Somers if (s1 == -1) { 123a8eb96d5SAlan Somers perror("accept"); 124a8eb96d5SAlan Somers atf_tc_fail("accept(2) failed"); 125a8eb96d5SAlan Somers } 126a8eb96d5SAlan Somers 1271f46c32cSGleb Smirnoff if (sv != NULL) { 128a8eb96d5SAlan Somers sv[0] = s1; 129a8eb96d5SAlan Somers sv[1] = s2; 1301f46c32cSGleb Smirnoff } 131e594026dSAlan Somers 132e594026dSAlan Somers close(s); 133e594026dSAlan Somers 1341f46c32cSGleb Smirnoff return (sun); 135a8eb96d5SAlan Somers } 136a8eb96d5SAlan Somers 137a8eb96d5SAlan Somers static volatile sig_atomic_t got_sigpipe = 0; 138a8eb96d5SAlan Somers static void 1395d5b721aSAlan Somers shutdown_send_sigpipe_handler(int __unused x) 140a8eb96d5SAlan Somers { 141a8eb96d5SAlan Somers got_sigpipe = 1; 142a8eb96d5SAlan Somers } 143a8eb96d5SAlan Somers 144a8eb96d5SAlan Somers /* 145a8eb96d5SAlan Somers * Parameterized test function bodies 146a8eb96d5SAlan Somers */ 1475d5b721aSAlan Somers static void 148ea703329SBrooks Davis test_eagain(int sndbufsize, int rcvbufsize) 149a8eb96d5SAlan Somers { 150a8eb96d5SAlan Somers int i; 151a8eb96d5SAlan Somers int sv[2]; 152a8eb96d5SAlan Somers const size_t totalsize = (sndbufsize + rcvbufsize) * 2; 153a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 1545d5b721aSAlan Somers const int numpkts = totalsize / pktsize; 155a8eb96d5SAlan Somers char sndbuf[pktsize]; 1565d5b721aSAlan Somers ssize_t ssize; 157a8eb96d5SAlan Somers 158a8eb96d5SAlan Somers /* setup the socket pair */ 159b9a9db10SAlan Somers do_socketpair_nonblocking(sv); 160a8eb96d5SAlan Somers /* Setup the buffers */ 161a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 162a8eb96d5SAlan Somers sizeof(sndbufsize))); 163a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 164a8eb96d5SAlan Somers sizeof(rcvbufsize))); 165a8eb96d5SAlan Somers 166a8eb96d5SAlan Somers bzero(sndbuf, pktsize); 167a8eb96d5SAlan Somers /* Send data until we get EAGAIN */ 1685d5b721aSAlan Somers for(i=0; i < numpkts; i++) { 169a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 170a8eb96d5SAlan Somers if (ssize == -1) { 171e594026dSAlan Somers if (errno == EAGAIN) { 172e594026dSAlan Somers close(sv[0]); 173e594026dSAlan Somers close(sv[1]); 174a8eb96d5SAlan Somers atf_tc_pass(); 175e594026dSAlan Somers } 176a8eb96d5SAlan Somers else { 177a8eb96d5SAlan Somers perror("send"); 178a8eb96d5SAlan Somers atf_tc_fail("send returned < 0 but not EAGAIN"); 179a8eb96d5SAlan Somers } 180a8eb96d5SAlan Somers } 181a8eb96d5SAlan Somers } 182a8eb96d5SAlan Somers atf_tc_fail("Never got EAGAIN"); 183a8eb96d5SAlan Somers } 184a8eb96d5SAlan Somers 1855d5b721aSAlan Somers static void 186ea703329SBrooks Davis test_sendrecv_symmetric_buffers(int bufsize, int blocking) { 187a8eb96d5SAlan Somers int s; 188a8eb96d5SAlan Somers int sv[2]; 1895d5b721aSAlan Somers const ssize_t pktsize = bufsize / 2; 190a8eb96d5SAlan Somers char sndbuf[pktsize]; 191a8eb96d5SAlan Somers char recv_buf[pktsize]; 192a8eb96d5SAlan Somers ssize_t ssize, rsize; 193a8eb96d5SAlan Somers 194a8eb96d5SAlan Somers /* setup the socket pair */ 195a8eb96d5SAlan Somers if (blocking) 196a8eb96d5SAlan Somers do_socketpair(sv); 197a8eb96d5SAlan Somers else 198a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 199a8eb96d5SAlan Somers 200a8eb96d5SAlan Somers /* Setup the buffers */ 201a8eb96d5SAlan Somers s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); 202a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 203a8eb96d5SAlan Somers s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); 204a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 205a8eb96d5SAlan Somers 206a8eb96d5SAlan Somers /* Fill the send buffer */ 207a8eb96d5SAlan Somers bzero(sndbuf, pktsize); 208a8eb96d5SAlan Somers 209a8eb96d5SAlan Somers /* send and receive the packet */ 210a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 211a8eb96d5SAlan Somers if (ssize < 0) { 212a8eb96d5SAlan Somers perror("send"); 213a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 214a8eb96d5SAlan Somers } 215a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd", 216a8eb96d5SAlan Somers pktsize, ssize); 217a8eb96d5SAlan Somers 218a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 219a8eb96d5SAlan Somers if (rsize < 0) { 220a8eb96d5SAlan Somers perror("recv"); 221a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 222a8eb96d5SAlan Somers } 223a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd", 224a8eb96d5SAlan Somers pktsize, rsize); 225e594026dSAlan Somers close(sv[0]); 226e594026dSAlan Somers close(sv[1]); 227a8eb96d5SAlan Somers } 228a8eb96d5SAlan Somers 2295d5b721aSAlan Somers static void 230ea703329SBrooks Davis test_pipe_simulator(int sndbufsize, int rcvbufsize) 231a8eb96d5SAlan Somers { 2325d5b721aSAlan Somers int num_sent, num_received; 233a8eb96d5SAlan Somers int sv[2]; 2345d5b721aSAlan Somers const ssize_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 235a8eb96d5SAlan Somers int numpkts; 236a8eb96d5SAlan Somers char sndbuf[pktsize]; 237a8eb96d5SAlan Somers char rcvbuf[pktsize]; 238a8eb96d5SAlan Somers char comparebuf[pktsize]; 239a8eb96d5SAlan Somers ssize_t ssize, rsize; 240a8eb96d5SAlan Somers bool currently_sending = true; 241a8eb96d5SAlan Somers 242a8eb96d5SAlan Somers /* setup the socket pair */ 243a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 244a8eb96d5SAlan Somers /* Setup the buffers */ 245a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 246a8eb96d5SAlan Somers sizeof(sndbufsize))); 247a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 248a8eb96d5SAlan Somers sizeof(rcvbufsize))); 249a8eb96d5SAlan Somers 250a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 251a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 252a8eb96d5SAlan Somers for (num_sent=0, num_received=0; 253a8eb96d5SAlan Somers num_sent < numpkts || num_received < numpkts; ) { 254a8eb96d5SAlan Somers if (currently_sending && num_sent < numpkts) { 255a8eb96d5SAlan Somers /* The simulated sending process */ 256a8eb96d5SAlan Somers /* fill the buffer */ 257a8eb96d5SAlan Somers memset(sndbuf, num_sent, pktsize); 258a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 259a8eb96d5SAlan Somers if (ssize < 0) { 260a8eb96d5SAlan Somers /* 261a8eb96d5SAlan Somers * XXX: This is bug-compatible with the kernel. 262a8eb96d5SAlan Somers * The kernel returns EMSGSIZE when it should 263a8eb96d5SAlan Somers * return EAGAIN 264a8eb96d5SAlan Somers */ 265a8eb96d5SAlan Somers if (errno == EAGAIN || errno == EMSGSIZE) 266a8eb96d5SAlan Somers currently_sending = false; 267a8eb96d5SAlan Somers else { 268a8eb96d5SAlan Somers perror("send"); 269a8eb96d5SAlan Somers atf_tc_fail("send failed"); 270a8eb96d5SAlan Somers } 271a8eb96d5SAlan Somers } else { 272a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 273a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 274a8eb96d5SAlan Somers pktsize, ssize); 275a8eb96d5SAlan Somers num_sent++; 276a8eb96d5SAlan Somers } 277a8eb96d5SAlan Somers } else { 278a8eb96d5SAlan Somers /* The simulated receiving process */ 279a8eb96d5SAlan Somers rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL); 280a8eb96d5SAlan Somers if (rsize < 0) { 281a8eb96d5SAlan Somers if (errno == EAGAIN) { 282a8eb96d5SAlan Somers currently_sending = true; 283a8eb96d5SAlan Somers ATF_REQUIRE_MSG(num_sent < numpkts, 284a8eb96d5SAlan Somers "Packets were lost!"); 285a8eb96d5SAlan Somers } 286a8eb96d5SAlan Somers else { 287a8eb96d5SAlan Somers perror("recv"); 288a8eb96d5SAlan Somers atf_tc_fail("recv failed"); 289a8eb96d5SAlan Somers } 290a8eb96d5SAlan Somers } else { 291a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 292a8eb96d5SAlan Somers "expected %zd=recv(...) but got %zd", 293a8eb96d5SAlan Somers pktsize, rsize); 294a8eb96d5SAlan Somers memset(comparebuf, num_received, pktsize); 295a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf, 296a8eb96d5SAlan Somers pktsize), 297a8eb96d5SAlan Somers "Received data miscompare"); 298a8eb96d5SAlan Somers num_received++; 299a8eb96d5SAlan Somers } 300a8eb96d5SAlan Somers } 301a8eb96d5SAlan Somers } 302e594026dSAlan Somers close(sv[0]); 303e594026dSAlan Somers close(sv[1]); 304a8eb96d5SAlan Somers } 305a8eb96d5SAlan Somers 306a8eb96d5SAlan Somers typedef struct { 307a8eb96d5SAlan Somers ssize_t pktsize; 308a8eb96d5SAlan Somers int numpkts; 309a8eb96d5SAlan Somers int so; 310a8eb96d5SAlan Somers } test_pipe_thread_data_t; 311a8eb96d5SAlan Somers 312a8eb96d5SAlan Somers static void* 313a8eb96d5SAlan Somers test_pipe_writer(void* args) 314a8eb96d5SAlan Somers { 315a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 316a8eb96d5SAlan Somers char sndbuf[td->pktsize]; 317a8eb96d5SAlan Somers ssize_t ssize; 318a8eb96d5SAlan Somers int i; 319a8eb96d5SAlan Somers 320a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 321a8eb96d5SAlan Somers memset(sndbuf, i, td->pktsize); 322a8eb96d5SAlan Somers ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR); 323a8eb96d5SAlan Somers if (ssize < 0) { 324a8eb96d5SAlan Somers perror("send"); 325a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 326a8eb96d5SAlan Somers } 327a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, ssize, 328a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 329a8eb96d5SAlan Somers td->pktsize, ssize); 330a8eb96d5SAlan Somers } 331a8eb96d5SAlan Somers return (0); 332a8eb96d5SAlan Somers } 333a8eb96d5SAlan Somers 334a8eb96d5SAlan Somers static void* 335a8eb96d5SAlan Somers test_pipe_reader(void* args) 336a8eb96d5SAlan Somers { 337a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 338a8eb96d5SAlan Somers char rcvbuf[td->pktsize]; 339a8eb96d5SAlan Somers char comparebuf[td->pktsize]; 340a8eb96d5SAlan Somers ssize_t rsize; 341a8eb96d5SAlan Somers int i, d; 342a8eb96d5SAlan Somers 343a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 344a8eb96d5SAlan Somers memset(comparebuf, i, td->pktsize); 345a8eb96d5SAlan Somers rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL); 346a8eb96d5SAlan Somers if (rsize < 0) { 347a8eb96d5SAlan Somers perror("recv"); 348a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 349a8eb96d5SAlan Somers } 350a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, rsize, 351a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 352a8eb96d5SAlan Somers td->pktsize, rsize); 353a8eb96d5SAlan Somers d = memcmp(comparebuf, rcvbuf, td->pktsize); 354a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, d, 355a8eb96d5SAlan Somers "Received data miscompare on packet %d", i); 356a8eb96d5SAlan Somers } 357a8eb96d5SAlan Somers return (0); 358a8eb96d5SAlan Somers } 359a8eb96d5SAlan Somers 360a8eb96d5SAlan Somers 3615d5b721aSAlan Somers static void 362ea703329SBrooks Davis test_pipe(int sndbufsize, int rcvbufsize) 363a8eb96d5SAlan Somers { 364a8eb96d5SAlan Somers test_pipe_thread_data_t writer_data, reader_data; 365a8eb96d5SAlan Somers pthread_t writer, reader; 366a8eb96d5SAlan Somers int sv[2]; 367a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 368a8eb96d5SAlan Somers int numpkts; 369a8eb96d5SAlan Somers 370a8eb96d5SAlan Somers /* setup the socket pair */ 371a8eb96d5SAlan Somers do_socketpair(sv); 372a8eb96d5SAlan Somers /* Setup the buffers */ 373a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 374a8eb96d5SAlan Somers sizeof(sndbufsize))); 375a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 376a8eb96d5SAlan Somers sizeof(rcvbufsize))); 377a8eb96d5SAlan Somers 378a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 379a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 380a8eb96d5SAlan Somers 381a8eb96d5SAlan Somers /* Start the child threads */ 382a8eb96d5SAlan Somers writer_data.pktsize = pktsize; 383a8eb96d5SAlan Somers writer_data.numpkts = numpkts; 384a8eb96d5SAlan Somers writer_data.so = sv[0]; 385a8eb96d5SAlan Somers reader_data.pktsize = pktsize; 386a8eb96d5SAlan Somers reader_data.numpkts = numpkts; 387a8eb96d5SAlan Somers reader_data.so = sv[1]; 388a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer, 389a8eb96d5SAlan Somers (void*)&writer_data)); 3908de34a88SAlan Somers /* 3918de34a88SAlan Somers * Give the writer time to start writing, and hopefully block, before 3928de34a88SAlan Somers * starting the reader. This increases the likelihood of the test case 3938de34a88SAlan Somers * failing due to PR kern/185812 3948de34a88SAlan Somers */ 3958de34a88SAlan Somers usleep(1000); 396a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader, 397a8eb96d5SAlan Somers (void*)&reader_data)); 398a8eb96d5SAlan Somers 399a8eb96d5SAlan Somers /* Join the children */ 400a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(writer, NULL)); 401a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(reader, NULL)); 402e594026dSAlan Somers close(sv[0]); 403e594026dSAlan Somers close(sv[1]); 404a8eb96d5SAlan Somers } 405a8eb96d5SAlan Somers 406a8eb96d5SAlan Somers 407a8eb96d5SAlan Somers /* 408a8eb96d5SAlan Somers * Test Cases 409a8eb96d5SAlan Somers */ 410a8eb96d5SAlan Somers 411a8eb96d5SAlan Somers /* Create a SEQPACKET socket */ 412a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socket); 413a8eb96d5SAlan Somers ATF_TC_BODY(create_socket, tc) 414a8eb96d5SAlan Somers { 415a8eb96d5SAlan Somers int s; 416a8eb96d5SAlan Somers 417a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 4186addc01eSAlan Somers ATF_REQUIRE(s >= 0); 419e594026dSAlan Somers close(s); 420a8eb96d5SAlan Somers } 421a8eb96d5SAlan Somers 422a8eb96d5SAlan Somers /* Create SEQPACKET sockets using socketpair(2) */ 423a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socketpair); 424a8eb96d5SAlan Somers ATF_TC_BODY(create_socketpair, tc) 425a8eb96d5SAlan Somers { 426a8eb96d5SAlan Somers int sv[2]; 427a8eb96d5SAlan Somers int s; 428a8eb96d5SAlan Somers 429a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 430a8eb96d5SAlan Somers ATF_CHECK_EQ(0, s); 431a8eb96d5SAlan Somers ATF_CHECK(sv[0] >= 0); 432a8eb96d5SAlan Somers ATF_CHECK(sv[1] >= 0); 433a8eb96d5SAlan Somers ATF_CHECK(sv[0] != sv[1]); 434e594026dSAlan Somers close(sv[0]); 435e594026dSAlan Somers close(sv[1]); 436a8eb96d5SAlan Somers } 437a8eb96d5SAlan Somers 438a8eb96d5SAlan Somers /* Call listen(2) without first calling bind(2). It should fail */ 439a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_unbound); 440a8eb96d5SAlan Somers ATF_TC_BODY(listen_unbound, tc) 441a8eb96d5SAlan Somers { 442a8eb96d5SAlan Somers int s, r; 443a8eb96d5SAlan Somers 444a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 445a8eb96d5SAlan Somers ATF_REQUIRE(s > 0); 446a8eb96d5SAlan Somers r = listen(s, -1); 447a8eb96d5SAlan Somers /* expect listen to fail since we haven't called bind(2) */ 448a8eb96d5SAlan Somers ATF_CHECK(r != 0); 449e594026dSAlan Somers close(s); 450a8eb96d5SAlan Somers } 451a8eb96d5SAlan Somers 452a8eb96d5SAlan Somers /* Bind the socket to a file */ 453a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(bind); 454a8eb96d5SAlan Somers ATF_TC_BODY(bind, tc) 455a8eb96d5SAlan Somers { 456a8eb96d5SAlan Somers struct sockaddr_un sun; 457a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 458a8eb96d5SAlan Somers const char *path = "sock"; 459a8eb96d5SAlan Somers int s, r; 460a8eb96d5SAlan Somers 461a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 462a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 463a8eb96d5SAlan Somers 464a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 465a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 466a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 467a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 468a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 469a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 470e594026dSAlan Somers close(s); 471a8eb96d5SAlan Somers } 472a8eb96d5SAlan Somers 473a8eb96d5SAlan Somers /* listen(2) a socket that is already bound(2) should succeed */ 474a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_bound); 475a8eb96d5SAlan Somers ATF_TC_BODY(listen_bound, tc) 476a8eb96d5SAlan Somers { 4771f46c32cSGleb Smirnoff int s; 478a8eb96d5SAlan Somers 4791f46c32cSGleb Smirnoff (void)mk_listening_socket(&s); 480e594026dSAlan Somers close(s); 481a8eb96d5SAlan Somers } 482a8eb96d5SAlan Somers 483a8eb96d5SAlan Somers /* connect(2) can make a connection */ 484a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(connect); 485a8eb96d5SAlan Somers ATF_TC_BODY(connect, tc) 486a8eb96d5SAlan Somers { 4871f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 4881f46c32cSGleb Smirnoff int s, err, s2; 489a8eb96d5SAlan Somers 4901f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 491a8eb96d5SAlan Somers 492a8eb96d5SAlan Somers /* Create the other socket */ 493a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 494a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 4951f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 496a8eb96d5SAlan Somers if (err != 0) { 497a8eb96d5SAlan Somers perror("connect"); 498a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 499a8eb96d5SAlan Somers } 500e594026dSAlan Somers close(s); 501e594026dSAlan Somers close(s2); 502a8eb96d5SAlan Somers } 503a8eb96d5SAlan Somers 5043bc122d2SGleb Smirnoff /* 5053bc122d2SGleb Smirnoff * An undocumented feature that we probably want to preserve: sending to 5063bc122d2SGleb Smirnoff * a socket that isn't yet accepted lands data on the socket. It can be 5073bc122d2SGleb Smirnoff * read after accept(2). 5083bc122d2SGleb Smirnoff */ 5093bc122d2SGleb Smirnoff ATF_TC_WITHOUT_HEAD(send_before_accept); 5103bc122d2SGleb Smirnoff ATF_TC_BODY(send_before_accept, tc) 5113bc122d2SGleb Smirnoff { 5123bc122d2SGleb Smirnoff const char buf[] = "hello"; 5133bc122d2SGleb Smirnoff char repl[sizeof(buf)]; 5143bc122d2SGleb Smirnoff const struct sockaddr_un *sun; 5153bc122d2SGleb Smirnoff int l, s, a; 5163bc122d2SGleb Smirnoff 5173bc122d2SGleb Smirnoff sun = mk_listening_socket(&l); 5183bc122d2SGleb Smirnoff 5193bc122d2SGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 5203bc122d2SGleb Smirnoff ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0); 5213bc122d2SGleb Smirnoff ATF_REQUIRE(send(s, &buf, sizeof(buf), 0) == sizeof(buf)); 5223bc122d2SGleb Smirnoff ATF_REQUIRE((a = accept(l, NULL, NULL)) != 1); 5233bc122d2SGleb Smirnoff ATF_REQUIRE(recv(a, &repl, sizeof(repl), 0) == sizeof(buf)); 5243bc122d2SGleb Smirnoff ATF_REQUIRE(strcmp(buf, repl) == 0); 5253bc122d2SGleb Smirnoff close(l); 5263bc122d2SGleb Smirnoff close(s); 5273bc122d2SGleb Smirnoff close(a); 5283bc122d2SGleb Smirnoff } 5293bc122d2SGleb Smirnoff 530253d8a1fSGleb Smirnoff /* Implied connect is unix/dgram only feature. Fails on stream or seqpacket. */ 531253d8a1fSGleb Smirnoff ATF_TC_WITHOUT_HEAD(implied_connect); 532253d8a1fSGleb Smirnoff ATF_TC_BODY(implied_connect, tc) 533253d8a1fSGleb Smirnoff { 534253d8a1fSGleb Smirnoff const struct sockaddr_un *sun; 535253d8a1fSGleb Smirnoff int l, s; 536253d8a1fSGleb Smirnoff 537253d8a1fSGleb Smirnoff sun = mk_listening_socket(&l); 538253d8a1fSGleb Smirnoff 539253d8a1fSGleb Smirnoff ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0); 540253d8a1fSGleb Smirnoff ATF_REQUIRE(sendto(s, &s, sizeof(s), 0, (struct sockaddr *)sun, 541253d8a1fSGleb Smirnoff sizeof(*sun)) == -1); 542253d8a1fSGleb Smirnoff ATF_REQUIRE(errno == ENOTCONN); 543253d8a1fSGleb Smirnoff close(l); 544253d8a1fSGleb Smirnoff close(s); 545253d8a1fSGleb Smirnoff } 546253d8a1fSGleb Smirnoff 547a8eb96d5SAlan Somers /* accept(2) can receive a connection */ 548a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(accept); 549a8eb96d5SAlan Somers ATF_TC_BODY(accept, tc) 550a8eb96d5SAlan Somers { 551a8eb96d5SAlan Somers int sv[2]; 552a8eb96d5SAlan Somers 553a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 554e594026dSAlan Somers close(sv[0]); 555e594026dSAlan Somers close(sv[1]); 556a8eb96d5SAlan Somers } 557a8eb96d5SAlan Somers 558a8eb96d5SAlan Somers 559a8eb96d5SAlan Somers /* Set O_NONBLOCK on the socket */ 560a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(fcntl_nonblock); 561a8eb96d5SAlan Somers ATF_TC_BODY(fcntl_nonblock, tc) 562a8eb96d5SAlan Somers { 563a8eb96d5SAlan Somers int s; 564a8eb96d5SAlan Somers 565a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 566a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 567a8eb96d5SAlan Somers if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) { 568a8eb96d5SAlan Somers perror("fcntl"); 569a8eb96d5SAlan Somers atf_tc_fail("fcntl failed"); 570a8eb96d5SAlan Somers } 571e594026dSAlan Somers close(s); 572a8eb96d5SAlan Somers } 573a8eb96d5SAlan Somers 574a8eb96d5SAlan Somers /* Resize the send and receive buffers */ 575a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_buffers); 576a8eb96d5SAlan Somers ATF_TC_BODY(resize_buffers, tc) 577a8eb96d5SAlan Somers { 578a8eb96d5SAlan Somers int s; 579a8eb96d5SAlan Somers int sndbuf = 12345; 580a8eb96d5SAlan Somers int rcvbuf = 23456; 581a8eb96d5SAlan Somers int xs, xr; 582a8eb96d5SAlan Somers socklen_t sl = sizeof(xs); 583a8eb96d5SAlan Somers 584a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 585a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 586a8eb96d5SAlan Somers 587a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 588a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF |\n"); 589a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 590a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 591a8eb96d5SAlan Somers printf("Default | %7d | %7d |\n", xs, xr); 592a8eb96d5SAlan Somers 593a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0){ 594a8eb96d5SAlan Somers perror("setsockopt"); 595a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 596a8eb96d5SAlan Somers } 597a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 598a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 599a8eb96d5SAlan Somers printf("After changing SNDBUF | %7d | %7d |\n", xs, xr); 600a8eb96d5SAlan Somers 601a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){ 602a8eb96d5SAlan Somers perror("setsockopt"); 603a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 604a8eb96d5SAlan Somers } 605a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 606a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 607a8eb96d5SAlan Somers printf("After changing RCVBUF | %7d | %7d |\n", xs, xr); 608e594026dSAlan Somers close(s); 609a8eb96d5SAlan Somers } 610a8eb96d5SAlan Somers 611a8eb96d5SAlan Somers /* 612a8eb96d5SAlan Somers * Resize the send and receive buffers of a connected socketpair 613a8eb96d5SAlan Somers * Print some useful debugging info too 614a8eb96d5SAlan Somers */ 615a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_connected_buffers); 616a8eb96d5SAlan Somers ATF_TC_BODY(resize_connected_buffers, tc) 617a8eb96d5SAlan Somers { 618a8eb96d5SAlan Somers int sv[2]; 619a8eb96d5SAlan Somers int sndbuf = 12345; 620a8eb96d5SAlan Somers int rcvbuf = 23456; 621a8eb96d5SAlan Somers int err; 622a8eb96d5SAlan Somers int ls, lr, rs, rr; 623a8eb96d5SAlan Somers socklen_t sl = sizeof(ls); 624a8eb96d5SAlan Somers 625a8eb96d5SAlan Somers /* setup the socket pair */ 626a8eb96d5SAlan Somers do_socketpair(sv); 627a8eb96d5SAlan Somers 628a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 629a8eb96d5SAlan Somers printf(" | Left Socket | Right Socket |\n"); 630a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF | SNDBUF | RCVBUF |\n"); 631a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 632a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 633a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 634a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 635a8eb96d5SAlan Somers printf("Default | %7d | %7d | %7d | %7d |\n", 636a8eb96d5SAlan Somers ls, lr, rs, rr); 637a8eb96d5SAlan Somers 638a8eb96d5SAlan Somers /* Update one side's send buffer */ 639a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 640a8eb96d5SAlan Somers if (err != 0){ 641a8eb96d5SAlan Somers perror("setsockopt"); 642a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 643a8eb96d5SAlan Somers } 644a8eb96d5SAlan Somers 645a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 646a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 647a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 648a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 649a8eb96d5SAlan Somers printf("After changing Left's SNDBUF | %7d | %7d | %7d | %7d |\n", 650a8eb96d5SAlan Somers ls, lr, rs, rr); 651a8eb96d5SAlan Somers 652a8eb96d5SAlan Somers /* Update the same side's receive buffer */ 653a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); 654a8eb96d5SAlan Somers if (err != 0){ 655a8eb96d5SAlan Somers perror("setsockopt"); 656a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 657a8eb96d5SAlan Somers } 658a8eb96d5SAlan Somers 659a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 660a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 661a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 662a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 663a8eb96d5SAlan Somers printf("After changing Left's RCVBUF | %7d | %7d | %7d | %7d |\n", 664a8eb96d5SAlan Somers ls, lr, rs, rr); 665e594026dSAlan Somers close(sv[0]); 666e594026dSAlan Somers close(sv[1]); 667a8eb96d5SAlan Somers } 668a8eb96d5SAlan Somers 669a8eb96d5SAlan Somers 670a8eb96d5SAlan Somers /* send(2) and recv(2) a single short record */ 671a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv); 672a8eb96d5SAlan Somers ATF_TC_BODY(send_recv, tc) 673a8eb96d5SAlan Somers { 674a8eb96d5SAlan Somers int sv[2]; 675a8eb96d5SAlan Somers const int bufsize = 64; 676a8eb96d5SAlan Somers const char *data = "data"; 677a8eb96d5SAlan Somers char recv_buf[bufsize]; 6785d5b721aSAlan Somers ssize_t datalen; 679a8eb96d5SAlan Somers ssize_t ssize, rsize; 680a8eb96d5SAlan Somers 681a8eb96d5SAlan Somers /* setup the socket pair */ 682a8eb96d5SAlan Somers do_socketpair(sv); 683a8eb96d5SAlan Somers 684a8eb96d5SAlan Somers /* send and receive a small packet */ 685a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 686a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 687a8eb96d5SAlan Somers if (ssize < 0) { 688a8eb96d5SAlan Somers perror("send"); 689a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 690a8eb96d5SAlan Somers } 691a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 692a8eb96d5SAlan Somers datalen, ssize); 693a8eb96d5SAlan Somers 694a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 695a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 696e594026dSAlan Somers close(sv[0]); 697e594026dSAlan Somers close(sv[1]); 698a8eb96d5SAlan Somers } 699a8eb96d5SAlan Somers 700a8eb96d5SAlan Somers /* sendto(2) and recvfrom(2) a single short record 701a8eb96d5SAlan Somers * According to The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 702a8eb96d5SAlan Somers * Edition, sendto(2) is exactly the same as send(2) on a connection-mode socket 703a8eb96d5SAlan Somers * 704a8eb96d5SAlan Somers * According to the same spec, not all protocols are required to provide the 705a8eb96d5SAlan Somers * source addres in recvfrom(2). 706a8eb96d5SAlan Somers */ 707a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendto_recvfrom); 708a8eb96d5SAlan Somers ATF_TC_BODY(sendto_recvfrom, tc) 709a8eb96d5SAlan Somers { 710983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 7111f46c32cSGleb Smirnoff const sockaddr_un *sun; 712983a2d91SEnji Cooper #endif 713a8eb96d5SAlan Somers struct sockaddr_storage from; 714a8eb96d5SAlan Somers int sv[2]; 715a8eb96d5SAlan Somers const int bufsize = 64; 716a8eb96d5SAlan Somers const char *data = "data"; 717a8eb96d5SAlan Somers char recv_buf[bufsize]; 7185d5b721aSAlan Somers ssize_t datalen; 719a8eb96d5SAlan Somers ssize_t ssize, rsize; 720a8eb96d5SAlan Somers socklen_t fromlen; 721a8eb96d5SAlan Somers 722a8eb96d5SAlan Somers /* setup the socket pair */ 723983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 7241f46c32cSGleb Smirnoff sun = 725983a2d91SEnji Cooper #endif 726983a2d91SEnji Cooper mk_pair_of_sockets(sv); 727a8eb96d5SAlan Somers 728a8eb96d5SAlan Somers /* send and receive a small packet */ 729a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 730a8eb96d5SAlan Somers ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0); 731a8eb96d5SAlan Somers if (ssize < 0) { 732a8eb96d5SAlan Somers perror("send"); 733a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 734a8eb96d5SAlan Somers } 735a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 736a8eb96d5SAlan Somers datalen, ssize); 737a8eb96d5SAlan Somers 738a8eb96d5SAlan Somers fromlen = sizeof(from); 739a8eb96d5SAlan Somers rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL, 740a8eb96d5SAlan Somers (struct sockaddr*)&from, &fromlen); 741a8eb96d5SAlan Somers if (ssize < 0) { 742a8eb96d5SAlan Somers perror("recvfrom"); 743a8eb96d5SAlan Somers atf_tc_fail("recvfrom returned < 0"); 744a8eb96d5SAlan Somers } 745a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 746a8eb96d5SAlan Somers 747983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 748a8eb96d5SAlan Somers /* 749a8eb96d5SAlan Somers * FreeBSD does not currently provide the source address for SEQ_PACKET 750a8eb96d5SAlan Somers * AF_UNIX sockets, and POSIX does not require it, so these two checks 751a8eb96d5SAlan Somers * are disabled. If FreeBSD gains that feature in the future, then 752a8eb96d5SAlan Somers * these checks may be reenabled 753a8eb96d5SAlan Somers */ 754983a2d91SEnji Cooper ATF_CHECK_EQ(PF_LOCAL, from.ss_family); 7551f46c32cSGleb Smirnoff ATF_CHECK_STREQ(sun->sun_path, ((struct sockaddr_un*)&from)->sun_path); 756983a2d91SEnji Cooper #endif 757e594026dSAlan Somers close(sv[0]); 758e594026dSAlan Somers close(sv[1]); 759a8eb96d5SAlan Somers } 760a8eb96d5SAlan Somers 761a8eb96d5SAlan Somers /* 762a8eb96d5SAlan Somers * send(2) and recv(2) a single short record with sockets created the 763a8eb96d5SAlan Somers * traditional way, involving bind, listen, connect, and accept 764a8eb96d5SAlan Somers */ 765a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_with_connect); 766a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_with_connect, tc) 767a8eb96d5SAlan Somers { 768a8eb96d5SAlan Somers int sv[2]; 769a8eb96d5SAlan Somers const int bufsize = 64; 770a8eb96d5SAlan Somers const char *data = "data"; 771a8eb96d5SAlan Somers char recv_buf[bufsize]; 7725d5b721aSAlan Somers ssize_t datalen; 773a8eb96d5SAlan Somers ssize_t ssize, rsize; 774a8eb96d5SAlan Somers 775a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 776a8eb96d5SAlan Somers 777a8eb96d5SAlan Somers /* send and receive a small packet */ 778a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 779a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 780a8eb96d5SAlan Somers if (ssize < 0) { 781a8eb96d5SAlan Somers perror("send"); 782a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 783a8eb96d5SAlan Somers } 784a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 785a8eb96d5SAlan Somers datalen, ssize); 786a8eb96d5SAlan Somers 787a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 788a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 789e594026dSAlan Somers close(sv[0]); 790e594026dSAlan Somers close(sv[1]); 791a8eb96d5SAlan Somers } 792a8eb96d5SAlan Somers 793a8eb96d5SAlan Somers /* send(2) should fail on a shutdown socket */ 794a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send); 795a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send, tc) 796a8eb96d5SAlan Somers { 7971f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 7984446a47aSSergey Kandaurov const char *data = "data"; 799fa5e5f53SEnji Cooper ssize_t datalen, ssize; 8004446a47aSSergey Kandaurov int s, err, s2; 801a8eb96d5SAlan Somers 8021f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 8034446a47aSSergey Kandaurov 8044446a47aSSergey Kandaurov /* Create the other socket */ 8054446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 8064446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 8071f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 8084446a47aSSergey Kandaurov if (err != 0) { 8094446a47aSSergey Kandaurov perror("connect"); 8104446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 8114446a47aSSergey Kandaurov } 8124446a47aSSergey Kandaurov 8134446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 814fa5e5f53SEnji Cooper datalen = strlen(data) + 1; /* +1 for the null */ 815a8eb96d5SAlan Somers /* USE MSG_NOSIGNAL so we don't get SIGPIPE */ 816fa5e5f53SEnji Cooper ssize = send(s2, data, datalen, MSG_EOR | MSG_NOSIGNAL); 817a8eb96d5SAlan Somers ATF_CHECK_EQ(EPIPE, errno); 818a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 819e594026dSAlan Somers close(s); 8204446a47aSSergey Kandaurov close(s2); 821a8eb96d5SAlan Somers } 822a8eb96d5SAlan Somers 823a8eb96d5SAlan Somers /* send(2) should cause SIGPIPE on a shutdown socket */ 824a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe); 825a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send_sigpipe, tc) 826a8eb96d5SAlan Somers { 8271f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 8284446a47aSSergey Kandaurov const char *data = "data"; 829fa5e5f53SEnji Cooper ssize_t datalen; 8304446a47aSSergey Kandaurov int s, err, s2; 831a8eb96d5SAlan Somers 8321f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 8334446a47aSSergey Kandaurov 8344446a47aSSergey Kandaurov /* Create the other socket */ 8354446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 8364446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 8371f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 8384446a47aSSergey Kandaurov if (err != 0) { 8394446a47aSSergey Kandaurov perror("connect"); 8404446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 8414446a47aSSergey Kandaurov } 8424446a47aSSergey Kandaurov 8434446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 844a8eb96d5SAlan Somers ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); 845fa5e5f53SEnji Cooper datalen = strlen(data) + 1; /* +1 for the null */ 8466dd202ceSJohn Baldwin (void)send(s2, data, datalen, MSG_EOR); 847a8eb96d5SAlan Somers ATF_CHECK_EQ(1, got_sigpipe); 848e594026dSAlan Somers close(s); 8494446a47aSSergey Kandaurov close(s2); 850a8eb96d5SAlan Somers } 851a8eb96d5SAlan Somers 852a8eb96d5SAlan Somers /* nonblocking send(2) and recv(2) a single short record */ 853a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 854a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_nonblocking, tc) 855a8eb96d5SAlan Somers { 856a8eb96d5SAlan Somers int sv[2]; 857a8eb96d5SAlan Somers const int bufsize = 64; 858a8eb96d5SAlan Somers const char *data = "data"; 859a8eb96d5SAlan Somers char recv_buf[bufsize]; 8605d5b721aSAlan Somers ssize_t datalen; 861a8eb96d5SAlan Somers ssize_t ssize, rsize; 862a8eb96d5SAlan Somers 863a8eb96d5SAlan Somers /* setup the socket pair */ 864a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 865a8eb96d5SAlan Somers 866a8eb96d5SAlan Somers /* Verify that there is nothing to receive */ 867a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 868a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 869a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 870a8eb96d5SAlan Somers 871a8eb96d5SAlan Somers /* send and receive a small packet */ 872a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 873a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 874a8eb96d5SAlan Somers if (ssize < 0) { 875a8eb96d5SAlan Somers perror("send"); 876a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 877a8eb96d5SAlan Somers } 878a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 879a8eb96d5SAlan Somers datalen, ssize); 880a8eb96d5SAlan Somers 881a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 882a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 883e594026dSAlan Somers close(sv[0]); 884e594026dSAlan Somers close(sv[1]); 885a8eb96d5SAlan Somers } 886a8eb96d5SAlan Somers 887a8eb96d5SAlan Somers /* 888a8eb96d5SAlan Somers * We should get EAGAIN if we try to send a message larger than the socket 889a8eb96d5SAlan Somers * buffer, with nonblocking sockets. Test with several different sockbuf sizes 890a8eb96d5SAlan Somers */ 891a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_8k); 892a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_8k, tc) 893a8eb96d5SAlan Somers { 894a8eb96d5SAlan Somers test_eagain(8192, 8192); 895a8eb96d5SAlan Somers } 896a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_128k); 897a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_128k, tc) 898a8eb96d5SAlan Somers { 899a8eb96d5SAlan Somers test_eagain(8192, 131072); 900a8eb96d5SAlan Somers } 901a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_8k); 902a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_8k, tc) 903a8eb96d5SAlan Somers { 904a8eb96d5SAlan Somers test_eagain(131072, 8192); 905a8eb96d5SAlan Somers } 906a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_128k); 907a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_128k, tc) 908a8eb96d5SAlan Somers { 909a8eb96d5SAlan Somers test_eagain(131072, 131072); 910a8eb96d5SAlan Somers } 911a8eb96d5SAlan Somers 912a8eb96d5SAlan Somers 913a8eb96d5SAlan Somers /* 914a8eb96d5SAlan Somers * nonblocking send(2) and recv(2) of several records, which should collectively 915a8eb96d5SAlan Somers * fill up the send buffer but not the receive buffer 916a8eb96d5SAlan Somers */ 917a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(rcvbuf_oversized); 918a8eb96d5SAlan Somers ATF_TC_BODY(rcvbuf_oversized, tc) 919a8eb96d5SAlan Somers { 9205d5b721aSAlan Somers int i; 921a8eb96d5SAlan Somers int sv[2]; 9223be7751dSJulio Merino const ssize_t pktsize = 1024; 923ea703329SBrooks Davis const int sndbufsize = 8192; 924ea703329SBrooks Davis const int rcvbufsize = 131072; 9255d5b721aSAlan Somers const size_t geometric_mean_bufsize = 32768; 9265d5b721aSAlan Somers const int numpkts = geometric_mean_bufsize / pktsize; 927a8eb96d5SAlan Somers char sndbuf[pktsize]; 928a8eb96d5SAlan Somers char recv_buf[pktsize]; 929a8eb96d5SAlan Somers ssize_t ssize, rsize; 930a8eb96d5SAlan Somers 931a8eb96d5SAlan Somers /* setup the socket pair */ 932a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 9335d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 9345d5b721aSAlan Somers sizeof(sndbufsize))); 9355d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 9365d5b721aSAlan Somers sizeof(rcvbufsize))); 937a8eb96d5SAlan Somers 938a8eb96d5SAlan Somers /* 939a8eb96d5SAlan Somers * Send and receive packets that are collectively greater than the send 940a8eb96d5SAlan Somers * buffer, but less than the receive buffer 941a8eb96d5SAlan Somers */ 9425d5b721aSAlan Somers for (i=0; i < numpkts; i++) { 943a8eb96d5SAlan Somers /* Fill the buffer */ 944a8eb96d5SAlan Somers memset(sndbuf, i, pktsize); 945a8eb96d5SAlan Somers 946a8eb96d5SAlan Somers /* send the packet */ 947a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 948a8eb96d5SAlan Somers if (ssize < 0) { 949a8eb96d5SAlan Somers perror("send"); 950a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 951a8eb96d5SAlan Somers } 952a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 953a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, ssize); 954a8eb96d5SAlan Somers 955a8eb96d5SAlan Somers /* Receive it */ 956a8eb96d5SAlan Somers 957a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 958a8eb96d5SAlan Somers if (rsize < 0) { 959a8eb96d5SAlan Somers perror("recv"); 960a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 961a8eb96d5SAlan Somers } 962a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 963a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, rsize); 964a8eb96d5SAlan Somers 965a8eb96d5SAlan Somers /* Verify the contents */ 966a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), 967a8eb96d5SAlan Somers "Received data miscompare"); 968a8eb96d5SAlan Somers } 969a8eb96d5SAlan Somers 970a8eb96d5SAlan Somers /* Trying to receive again should return EAGAIN */ 971a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 972a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 973a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 974e594026dSAlan Somers close(sv[0]); 975e594026dSAlan Somers close(sv[1]); 976a8eb96d5SAlan Somers } 977a8eb96d5SAlan Somers 978a8eb96d5SAlan Somers /* 979a8eb96d5SAlan Somers * Simulate the behavior of a blocking pipe. The sender will send until his 980a8eb96d5SAlan Somers * buffer fills up, then we'll simulate a scheduler switch that will allow the 981a8eb96d5SAlan Somers * receiver to read until his buffer empties. Repeat the process until the 982a8eb96d5SAlan Somers * transfer is complete. 983a8eb96d5SAlan Somers * Repeat the test with multiple send and receive buffer sizes 984a8eb96d5SAlan Somers */ 985a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k); 986a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_8k, tc) 987a8eb96d5SAlan Somers { 988a8eb96d5SAlan Somers test_pipe_simulator(8192, 8192); 989a8eb96d5SAlan Somers } 990a8eb96d5SAlan Somers 991a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k); 992a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_128k, tc) 993a8eb96d5SAlan Somers { 994a8eb96d5SAlan Somers test_pipe_simulator(8192, 131072); 995a8eb96d5SAlan Somers } 996a8eb96d5SAlan Somers 997a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k); 998a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_8k, tc) 999a8eb96d5SAlan Somers { 1000a8eb96d5SAlan Somers test_pipe_simulator(131072, 8192); 1001a8eb96d5SAlan Somers } 1002a8eb96d5SAlan Somers 1003a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k); 1004a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_128k, tc) 1005a8eb96d5SAlan Somers { 1006a8eb96d5SAlan Somers test_pipe_simulator(131072, 131072); 1007a8eb96d5SAlan Somers } 1008a8eb96d5SAlan Somers 1009a8eb96d5SAlan Somers /* 1010a8eb96d5SAlan Somers * Test blocking I/O by passing data between two threads. The total amount of 1011a8eb96d5SAlan Somers * data will be >> buffer size to force blocking. Repeat the test with multiple 1012a8eb96d5SAlan Somers * send and receive buffer sizes 1013a8eb96d5SAlan Somers */ 1014a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_8k); 1015a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_8k, tc) 1016a8eb96d5SAlan Somers { 1017a8eb96d5SAlan Somers test_pipe(8192, 8192); 1018a8eb96d5SAlan Somers } 1019a8eb96d5SAlan Somers 1020a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_128k); 1021a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_128k, tc) 1022a8eb96d5SAlan Somers { 1023a8eb96d5SAlan Somers test_pipe(8192, 131072); 1024a8eb96d5SAlan Somers } 1025a8eb96d5SAlan Somers 1026a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_8k); 1027a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_8k, tc) 1028a8eb96d5SAlan Somers { 1029a8eb96d5SAlan Somers test_pipe(131072, 8192); 1030a8eb96d5SAlan Somers } 1031a8eb96d5SAlan Somers 1032a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_128k); 1033a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_128k, tc) 1034a8eb96d5SAlan Somers { 1035a8eb96d5SAlan Somers test_pipe(131072, 131072); 1036a8eb96d5SAlan Somers } 1037a8eb96d5SAlan Somers 1038a8eb96d5SAlan Somers 1039a8eb96d5SAlan Somers /* 1040a8eb96d5SAlan Somers * Test single-packet I/O with and without blocking, with symmetric buffers of 1041a8eb96d5SAlan Somers * various sizes 1042a8eb96d5SAlan Somers */ 1043a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k); 1044a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k, tc) 1045a8eb96d5SAlan Somers { 1046a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, true); 1047a8eb96d5SAlan Somers } 1048a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k); 1049a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k, tc) 1050a8eb96d5SAlan Somers { 1051a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, true); 1052a8eb96d5SAlan Somers } 1053a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k); 1054a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k, tc) 1055a8eb96d5SAlan Somers { 1056a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, true); 1057a8eb96d5SAlan Somers } 1058a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k); 1059a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k, tc) 1060a8eb96d5SAlan Somers { 1061a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, true); 1062a8eb96d5SAlan Somers } 1063a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k); 1064a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k, tc) 1065a8eb96d5SAlan Somers { 1066a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, true); 1067a8eb96d5SAlan Somers } 1068a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking); 1069a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k_nonblocking, tc) 1070a8eb96d5SAlan Somers { 1071a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, false); 1072a8eb96d5SAlan Somers } 1073a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking); 1074a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k_nonblocking, tc) 1075a8eb96d5SAlan Somers { 1076a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, false); 1077a8eb96d5SAlan Somers } 1078a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking); 1079a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k_nonblocking, tc) 1080a8eb96d5SAlan Somers { 1081a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, false); 1082a8eb96d5SAlan Somers } 1083a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking); 1084a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k_nonblocking, tc) 1085a8eb96d5SAlan Somers { 1086a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, false); 1087a8eb96d5SAlan Somers } 1088a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking); 1089a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k_nonblocking, tc) 1090a8eb96d5SAlan Somers { 1091a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, false); 1092a8eb96d5SAlan Somers } 1093a8eb96d5SAlan Somers 1094a8eb96d5SAlan Somers 1095a8eb96d5SAlan Somers /* 1096a8eb96d5SAlan Somers * Main. 1097a8eb96d5SAlan Somers */ 1098a8eb96d5SAlan Somers 1099a8eb96d5SAlan Somers ATF_TP_ADD_TCS(tp) 1100a8eb96d5SAlan Somers { 1101a8eb96d5SAlan Somers /* Basic creation and connection tests */ 1102a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socket); 1103a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socketpair); 1104a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_unbound); 1105a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, bind); 1106a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_bound); 1107a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, connect); 1108a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, accept); 1109a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, fcntl_nonblock); 1110a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_buffers); 1111a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_connected_buffers); 1112a8eb96d5SAlan Somers 1113a8eb96d5SAlan Somers /* Unthreaded I/O tests */ 1114a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv); 1115a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_nonblocking); 1116a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_with_connect); 1117a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendto_recvfrom); 11183bc122d2SGleb Smirnoff ATF_TP_ADD_TC(tp, send_before_accept); 1119253d8a1fSGleb Smirnoff ATF_TP_ADD_TC(tp, implied_connect); 1120a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send); 1121a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send_sigpipe); 1122a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_8k); 1123a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_128k); 1124a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_8k); 1125a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_128k); 1126a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k); 1127a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k); 1128a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k); 1129a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k); 1130a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k); 1131a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking); 1132a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking); 1133a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking); 1134a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking); 1135a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking); 1136a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, rcvbuf_oversized); 1137a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k); 1138a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k); 1139a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k); 1140a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k); 1141a8eb96d5SAlan Somers 1142a8eb96d5SAlan Somers /* Threaded I/O tests with blocking sockets */ 1143a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_8k); 1144a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_128k); 1145a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_8k); 1146a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_128k); 1147a8eb96d5SAlan Somers 1148a8eb96d5SAlan Somers return atf_no_error(); 1149a8eb96d5SAlan Somers } 1150