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 /* 71*1f46c32cSGleb Smirnoff * Returns a bound and listening socket. 72a8eb96d5SAlan Somers * @return const char* The path to the socket 73a8eb96d5SAlan Somers */ 74*1f46c32cSGleb Smirnoff static const struct sockaddr_un * 75*1f46c32cSGleb Smirnoff mk_listening_socket(int *sv) 76a8eb96d5SAlan Somers { 77a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 78*1f46c32cSGleb Smirnoff static const struct sockaddr_un sun = { 79*1f46c32cSGleb Smirnoff .sun_family = AF_LOCAL, 80*1f46c32cSGleb Smirnoff .sun_len = sizeof(sun), 81*1f46c32cSGleb Smirnoff .sun_path = "sock", 82*1f46c32cSGleb Smirnoff }; 83*1f46c32cSGleb Smirnoff int s, r, l; 84a8eb96d5SAlan Somers 85a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 86a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 87a8eb96d5SAlan Somers 88*1f46c32cSGleb Smirnoff r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 89*1f46c32cSGleb Smirnoff l = listen(s, -1); 90*1f46c32cSGleb Smirnoff ATF_CHECK_EQ(0, r); 91*1f46c32cSGleb Smirnoff ATF_CHECK_EQ(0, l); 92*1f46c32cSGleb Smirnoff 93*1f46c32cSGleb Smirnoff if (sv != NULL) 94*1f46c32cSGleb Smirnoff *sv = s; 95*1f46c32cSGleb Smirnoff 96*1f46c32cSGleb Smirnoff return (&sun); 97*1f46c32cSGleb Smirnoff } 98*1f46c32cSGleb Smirnoff 99*1f46c32cSGleb Smirnoff /* 100*1f46c32cSGleb Smirnoff * Returns a pair of sockets made the hard way: bind, listen, connect & accept 101*1f46c32cSGleb Smirnoff * @return const char* The path to the socket 102*1f46c32cSGleb Smirnoff */ 103*1f46c32cSGleb Smirnoff static const struct sockaddr_un * 104*1f46c32cSGleb Smirnoff mk_pair_of_sockets(int *sv) 105*1f46c32cSGleb Smirnoff { 106*1f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 107*1f46c32cSGleb Smirnoff int s, s2, err, s1; 108*1f46c32cSGleb Smirnoff 109*1f46c32cSGleb 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); 114*1f46c32cSGleb 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 127*1f46c32cSGleb Smirnoff if (sv != NULL) { 128a8eb96d5SAlan Somers sv[0] = s1; 129a8eb96d5SAlan Somers sv[1] = s2; 130*1f46c32cSGleb Smirnoff } 131e594026dSAlan Somers 132e594026dSAlan Somers close(s); 133e594026dSAlan Somers 134*1f46c32cSGleb 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 { 477*1f46c32cSGleb Smirnoff int s; 478a8eb96d5SAlan Somers 479*1f46c32cSGleb 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 { 487*1f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 488*1f46c32cSGleb Smirnoff int s, err, s2; 489a8eb96d5SAlan Somers 490*1f46c32cSGleb 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); 495*1f46c32cSGleb 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 504a8eb96d5SAlan Somers /* accept(2) can receive a connection */ 505a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(accept); 506a8eb96d5SAlan Somers ATF_TC_BODY(accept, tc) 507a8eb96d5SAlan Somers { 508a8eb96d5SAlan Somers int sv[2]; 509a8eb96d5SAlan Somers 510a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 511e594026dSAlan Somers close(sv[0]); 512e594026dSAlan Somers close(sv[1]); 513a8eb96d5SAlan Somers } 514a8eb96d5SAlan Somers 515a8eb96d5SAlan Somers 516a8eb96d5SAlan Somers /* Set O_NONBLOCK on the socket */ 517a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(fcntl_nonblock); 518a8eb96d5SAlan Somers ATF_TC_BODY(fcntl_nonblock, tc) 519a8eb96d5SAlan Somers { 520a8eb96d5SAlan Somers int s; 521a8eb96d5SAlan Somers 522a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 523a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 524a8eb96d5SAlan Somers if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) { 525a8eb96d5SAlan Somers perror("fcntl"); 526a8eb96d5SAlan Somers atf_tc_fail("fcntl failed"); 527a8eb96d5SAlan Somers } 528e594026dSAlan Somers close(s); 529a8eb96d5SAlan Somers } 530a8eb96d5SAlan Somers 531a8eb96d5SAlan Somers /* Resize the send and receive buffers */ 532a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_buffers); 533a8eb96d5SAlan Somers ATF_TC_BODY(resize_buffers, tc) 534a8eb96d5SAlan Somers { 535a8eb96d5SAlan Somers int s; 536a8eb96d5SAlan Somers int sndbuf = 12345; 537a8eb96d5SAlan Somers int rcvbuf = 23456; 538a8eb96d5SAlan Somers int xs, xr; 539a8eb96d5SAlan Somers socklen_t sl = sizeof(xs); 540a8eb96d5SAlan Somers 541a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 542a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 543a8eb96d5SAlan Somers 544a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 545a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF |\n"); 546a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 547a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 548a8eb96d5SAlan Somers printf("Default | %7d | %7d |\n", xs, xr); 549a8eb96d5SAlan Somers 550a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0){ 551a8eb96d5SAlan Somers perror("setsockopt"); 552a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 553a8eb96d5SAlan Somers } 554a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 555a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 556a8eb96d5SAlan Somers printf("After changing SNDBUF | %7d | %7d |\n", xs, xr); 557a8eb96d5SAlan Somers 558a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){ 559a8eb96d5SAlan Somers perror("setsockopt"); 560a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 561a8eb96d5SAlan Somers } 562a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 563a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 564a8eb96d5SAlan Somers printf("After changing RCVBUF | %7d | %7d |\n", xs, xr); 565e594026dSAlan Somers close(s); 566a8eb96d5SAlan Somers } 567a8eb96d5SAlan Somers 568a8eb96d5SAlan Somers /* 569a8eb96d5SAlan Somers * Resize the send and receive buffers of a connected socketpair 570a8eb96d5SAlan Somers * Print some useful debugging info too 571a8eb96d5SAlan Somers */ 572a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_connected_buffers); 573a8eb96d5SAlan Somers ATF_TC_BODY(resize_connected_buffers, tc) 574a8eb96d5SAlan Somers { 575a8eb96d5SAlan Somers int sv[2]; 576a8eb96d5SAlan Somers int sndbuf = 12345; 577a8eb96d5SAlan Somers int rcvbuf = 23456; 578a8eb96d5SAlan Somers int err; 579a8eb96d5SAlan Somers int ls, lr, rs, rr; 580a8eb96d5SAlan Somers socklen_t sl = sizeof(ls); 581a8eb96d5SAlan Somers 582a8eb96d5SAlan Somers /* setup the socket pair */ 583a8eb96d5SAlan Somers do_socketpair(sv); 584a8eb96d5SAlan Somers 585a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 586a8eb96d5SAlan Somers printf(" | Left Socket | Right Socket |\n"); 587a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF | SNDBUF | RCVBUF |\n"); 588a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 589a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 590a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 591a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 592a8eb96d5SAlan Somers printf("Default | %7d | %7d | %7d | %7d |\n", 593a8eb96d5SAlan Somers ls, lr, rs, rr); 594a8eb96d5SAlan Somers 595a8eb96d5SAlan Somers /* Update one side's send buffer */ 596a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 597a8eb96d5SAlan Somers if (err != 0){ 598a8eb96d5SAlan Somers perror("setsockopt"); 599a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 600a8eb96d5SAlan Somers } 601a8eb96d5SAlan Somers 602a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 603a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 604a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 605a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 606a8eb96d5SAlan Somers printf("After changing Left's SNDBUF | %7d | %7d | %7d | %7d |\n", 607a8eb96d5SAlan Somers ls, lr, rs, rr); 608a8eb96d5SAlan Somers 609a8eb96d5SAlan Somers /* Update the same side's receive buffer */ 610a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); 611a8eb96d5SAlan Somers if (err != 0){ 612a8eb96d5SAlan Somers perror("setsockopt"); 613a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 614a8eb96d5SAlan Somers } 615a8eb96d5SAlan Somers 616a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 617a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 618a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 619a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 620a8eb96d5SAlan Somers printf("After changing Left's RCVBUF | %7d | %7d | %7d | %7d |\n", 621a8eb96d5SAlan Somers ls, lr, rs, rr); 622e594026dSAlan Somers close(sv[0]); 623e594026dSAlan Somers close(sv[1]); 624a8eb96d5SAlan Somers } 625a8eb96d5SAlan Somers 626a8eb96d5SAlan Somers 627a8eb96d5SAlan Somers /* send(2) and recv(2) a single short record */ 628a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv); 629a8eb96d5SAlan Somers ATF_TC_BODY(send_recv, tc) 630a8eb96d5SAlan Somers { 631a8eb96d5SAlan Somers int sv[2]; 632a8eb96d5SAlan Somers const int bufsize = 64; 633a8eb96d5SAlan Somers const char *data = "data"; 634a8eb96d5SAlan Somers char recv_buf[bufsize]; 6355d5b721aSAlan Somers ssize_t datalen; 636a8eb96d5SAlan Somers ssize_t ssize, rsize; 637a8eb96d5SAlan Somers 638a8eb96d5SAlan Somers /* setup the socket pair */ 639a8eb96d5SAlan Somers do_socketpair(sv); 640a8eb96d5SAlan Somers 641a8eb96d5SAlan Somers /* send and receive a small packet */ 642a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 643a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 644a8eb96d5SAlan Somers if (ssize < 0) { 645a8eb96d5SAlan Somers perror("send"); 646a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 647a8eb96d5SAlan Somers } 648a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 649a8eb96d5SAlan Somers datalen, ssize); 650a8eb96d5SAlan Somers 651a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 652a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 653e594026dSAlan Somers close(sv[0]); 654e594026dSAlan Somers close(sv[1]); 655a8eb96d5SAlan Somers } 656a8eb96d5SAlan Somers 657a8eb96d5SAlan Somers /* sendto(2) and recvfrom(2) a single short record 658a8eb96d5SAlan Somers * According to The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 659a8eb96d5SAlan Somers * Edition, sendto(2) is exactly the same as send(2) on a connection-mode socket 660a8eb96d5SAlan Somers * 661a8eb96d5SAlan Somers * According to the same spec, not all protocols are required to provide the 662a8eb96d5SAlan Somers * source addres in recvfrom(2). 663a8eb96d5SAlan Somers */ 664a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendto_recvfrom); 665a8eb96d5SAlan Somers ATF_TC_BODY(sendto_recvfrom, tc) 666a8eb96d5SAlan Somers { 667983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 668*1f46c32cSGleb Smirnoff const sockaddr_un *sun; 669983a2d91SEnji Cooper #endif 670a8eb96d5SAlan Somers struct sockaddr_storage from; 671a8eb96d5SAlan Somers int sv[2]; 672a8eb96d5SAlan Somers const int bufsize = 64; 673a8eb96d5SAlan Somers const char *data = "data"; 674a8eb96d5SAlan Somers char recv_buf[bufsize]; 6755d5b721aSAlan Somers ssize_t datalen; 676a8eb96d5SAlan Somers ssize_t ssize, rsize; 677a8eb96d5SAlan Somers socklen_t fromlen; 678a8eb96d5SAlan Somers 679a8eb96d5SAlan Somers /* setup the socket pair */ 680983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 681*1f46c32cSGleb Smirnoff sun = 682983a2d91SEnji Cooper #endif 683983a2d91SEnji Cooper mk_pair_of_sockets(sv); 684a8eb96d5SAlan Somers 685a8eb96d5SAlan Somers /* send and receive a small packet */ 686a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 687a8eb96d5SAlan Somers ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0); 688a8eb96d5SAlan Somers if (ssize < 0) { 689a8eb96d5SAlan Somers perror("send"); 690a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 691a8eb96d5SAlan Somers } 692a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 693a8eb96d5SAlan Somers datalen, ssize); 694a8eb96d5SAlan Somers 695a8eb96d5SAlan Somers fromlen = sizeof(from); 696a8eb96d5SAlan Somers rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL, 697a8eb96d5SAlan Somers (struct sockaddr*)&from, &fromlen); 698a8eb96d5SAlan Somers if (ssize < 0) { 699a8eb96d5SAlan Somers perror("recvfrom"); 700a8eb96d5SAlan Somers atf_tc_fail("recvfrom returned < 0"); 701a8eb96d5SAlan Somers } 702a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 703a8eb96d5SAlan Somers 704983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 705a8eb96d5SAlan Somers /* 706a8eb96d5SAlan Somers * FreeBSD does not currently provide the source address for SEQ_PACKET 707a8eb96d5SAlan Somers * AF_UNIX sockets, and POSIX does not require it, so these two checks 708a8eb96d5SAlan Somers * are disabled. If FreeBSD gains that feature in the future, then 709a8eb96d5SAlan Somers * these checks may be reenabled 710a8eb96d5SAlan Somers */ 711983a2d91SEnji Cooper ATF_CHECK_EQ(PF_LOCAL, from.ss_family); 712*1f46c32cSGleb Smirnoff ATF_CHECK_STREQ(sun->sun_path, ((struct sockaddr_un*)&from)->sun_path); 713983a2d91SEnji Cooper #endif 714e594026dSAlan Somers close(sv[0]); 715e594026dSAlan Somers close(sv[1]); 716a8eb96d5SAlan Somers } 717a8eb96d5SAlan Somers 718a8eb96d5SAlan Somers /* 719a8eb96d5SAlan Somers * send(2) and recv(2) a single short record with sockets created the 720a8eb96d5SAlan Somers * traditional way, involving bind, listen, connect, and accept 721a8eb96d5SAlan Somers */ 722a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_with_connect); 723a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_with_connect, tc) 724a8eb96d5SAlan Somers { 725a8eb96d5SAlan Somers int sv[2]; 726a8eb96d5SAlan Somers const int bufsize = 64; 727a8eb96d5SAlan Somers const char *data = "data"; 728a8eb96d5SAlan Somers char recv_buf[bufsize]; 7295d5b721aSAlan Somers ssize_t datalen; 730a8eb96d5SAlan Somers ssize_t ssize, rsize; 731a8eb96d5SAlan Somers 732a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 733a8eb96d5SAlan Somers 734a8eb96d5SAlan Somers /* send and receive a small packet */ 735a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 736a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 737a8eb96d5SAlan Somers if (ssize < 0) { 738a8eb96d5SAlan Somers perror("send"); 739a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 740a8eb96d5SAlan Somers } 741a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 742a8eb96d5SAlan Somers datalen, ssize); 743a8eb96d5SAlan Somers 744a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 745a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 746e594026dSAlan Somers close(sv[0]); 747e594026dSAlan Somers close(sv[1]); 748a8eb96d5SAlan Somers } 749a8eb96d5SAlan Somers 750a8eb96d5SAlan Somers /* send(2) should fail on a shutdown socket */ 751a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send); 752a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send, tc) 753a8eb96d5SAlan Somers { 754*1f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 7554446a47aSSergey Kandaurov const char *data = "data"; 756fa5e5f53SEnji Cooper ssize_t datalen, ssize; 7574446a47aSSergey Kandaurov int s, err, s2; 758a8eb96d5SAlan Somers 759*1f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 7604446a47aSSergey Kandaurov 7614446a47aSSergey Kandaurov /* Create the other socket */ 7624446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 7634446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 764*1f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 7654446a47aSSergey Kandaurov if (err != 0) { 7664446a47aSSergey Kandaurov perror("connect"); 7674446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 7684446a47aSSergey Kandaurov } 7694446a47aSSergey Kandaurov 7704446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 771fa5e5f53SEnji Cooper datalen = strlen(data) + 1; /* +1 for the null */ 772a8eb96d5SAlan Somers /* USE MSG_NOSIGNAL so we don't get SIGPIPE */ 773fa5e5f53SEnji Cooper ssize = send(s2, data, datalen, MSG_EOR | MSG_NOSIGNAL); 774a8eb96d5SAlan Somers ATF_CHECK_EQ(EPIPE, errno); 775a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 776e594026dSAlan Somers close(s); 7774446a47aSSergey Kandaurov close(s2); 778a8eb96d5SAlan Somers } 779a8eb96d5SAlan Somers 780a8eb96d5SAlan Somers /* send(2) should cause SIGPIPE on a shutdown socket */ 781a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe); 782a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send_sigpipe, tc) 783a8eb96d5SAlan Somers { 784*1f46c32cSGleb Smirnoff const struct sockaddr_un *sun; 7854446a47aSSergey Kandaurov const char *data = "data"; 786fa5e5f53SEnji Cooper ssize_t datalen; 7874446a47aSSergey Kandaurov int s, err, s2; 788a8eb96d5SAlan Somers 789*1f46c32cSGleb Smirnoff sun = mk_listening_socket(&s); 7904446a47aSSergey Kandaurov 7914446a47aSSergey Kandaurov /* Create the other socket */ 7924446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 7934446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 794*1f46c32cSGleb Smirnoff err = connect(s2, (struct sockaddr *)sun, sizeof(*sun)); 7954446a47aSSergey Kandaurov if (err != 0) { 7964446a47aSSergey Kandaurov perror("connect"); 7974446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 7984446a47aSSergey Kandaurov } 7994446a47aSSergey Kandaurov 8004446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 801a8eb96d5SAlan Somers ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); 802fa5e5f53SEnji Cooper datalen = strlen(data) + 1; /* +1 for the null */ 8036dd202ceSJohn Baldwin (void)send(s2, data, datalen, MSG_EOR); 804a8eb96d5SAlan Somers ATF_CHECK_EQ(1, got_sigpipe); 805e594026dSAlan Somers close(s); 8064446a47aSSergey Kandaurov close(s2); 807a8eb96d5SAlan Somers } 808a8eb96d5SAlan Somers 809a8eb96d5SAlan Somers /* nonblocking send(2) and recv(2) a single short record */ 810a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 811a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_nonblocking, 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 /* setup the socket pair */ 821a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 822a8eb96d5SAlan Somers 823a8eb96d5SAlan Somers /* Verify that there is nothing to receive */ 824a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 825a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 826a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 827a8eb96d5SAlan Somers 828a8eb96d5SAlan Somers /* send and receive a small packet */ 829a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 830a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 831a8eb96d5SAlan Somers if (ssize < 0) { 832a8eb96d5SAlan Somers perror("send"); 833a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 834a8eb96d5SAlan Somers } 835a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 836a8eb96d5SAlan Somers datalen, ssize); 837a8eb96d5SAlan Somers 838a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 839a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 840e594026dSAlan Somers close(sv[0]); 841e594026dSAlan Somers close(sv[1]); 842a8eb96d5SAlan Somers } 843a8eb96d5SAlan Somers 844a8eb96d5SAlan Somers /* 845a8eb96d5SAlan Somers * We should get EAGAIN if we try to send a message larger than the socket 846a8eb96d5SAlan Somers * buffer, with nonblocking sockets. Test with several different sockbuf sizes 847a8eb96d5SAlan Somers */ 848a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_8k); 849a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_8k, tc) 850a8eb96d5SAlan Somers { 851a8eb96d5SAlan Somers test_eagain(8192, 8192); 852a8eb96d5SAlan Somers } 853a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_128k); 854a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_128k, tc) 855a8eb96d5SAlan Somers { 856a8eb96d5SAlan Somers test_eagain(8192, 131072); 857a8eb96d5SAlan Somers } 858a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_8k); 859a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_8k, tc) 860a8eb96d5SAlan Somers { 861a8eb96d5SAlan Somers test_eagain(131072, 8192); 862a8eb96d5SAlan Somers } 863a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_128k); 864a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_128k, tc) 865a8eb96d5SAlan Somers { 866a8eb96d5SAlan Somers test_eagain(131072, 131072); 867a8eb96d5SAlan Somers } 868a8eb96d5SAlan Somers 869a8eb96d5SAlan Somers 870a8eb96d5SAlan Somers /* 871a8eb96d5SAlan Somers * nonblocking send(2) and recv(2) of several records, which should collectively 872a8eb96d5SAlan Somers * fill up the send buffer but not the receive buffer 873a8eb96d5SAlan Somers */ 874a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(rcvbuf_oversized); 875a8eb96d5SAlan Somers ATF_TC_BODY(rcvbuf_oversized, tc) 876a8eb96d5SAlan Somers { 8775d5b721aSAlan Somers int i; 878a8eb96d5SAlan Somers int sv[2]; 8793be7751dSJulio Merino const ssize_t pktsize = 1024; 880ea703329SBrooks Davis const int sndbufsize = 8192; 881ea703329SBrooks Davis const int rcvbufsize = 131072; 8825d5b721aSAlan Somers const size_t geometric_mean_bufsize = 32768; 8835d5b721aSAlan Somers const int numpkts = geometric_mean_bufsize / pktsize; 884a8eb96d5SAlan Somers char sndbuf[pktsize]; 885a8eb96d5SAlan Somers char recv_buf[pktsize]; 886a8eb96d5SAlan Somers ssize_t ssize, rsize; 887a8eb96d5SAlan Somers 888a8eb96d5SAlan Somers /* setup the socket pair */ 889a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 8905d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 8915d5b721aSAlan Somers sizeof(sndbufsize))); 8925d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 8935d5b721aSAlan Somers sizeof(rcvbufsize))); 894a8eb96d5SAlan Somers 895a8eb96d5SAlan Somers /* 896a8eb96d5SAlan Somers * Send and receive packets that are collectively greater than the send 897a8eb96d5SAlan Somers * buffer, but less than the receive buffer 898a8eb96d5SAlan Somers */ 8995d5b721aSAlan Somers for (i=0; i < numpkts; i++) { 900a8eb96d5SAlan Somers /* Fill the buffer */ 901a8eb96d5SAlan Somers memset(sndbuf, i, pktsize); 902a8eb96d5SAlan Somers 903a8eb96d5SAlan Somers /* send the packet */ 904a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 905a8eb96d5SAlan Somers if (ssize < 0) { 906a8eb96d5SAlan Somers perror("send"); 907a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 908a8eb96d5SAlan Somers } 909a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 910a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, ssize); 911a8eb96d5SAlan Somers 912a8eb96d5SAlan Somers /* Receive it */ 913a8eb96d5SAlan Somers 914a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 915a8eb96d5SAlan Somers if (rsize < 0) { 916a8eb96d5SAlan Somers perror("recv"); 917a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 918a8eb96d5SAlan Somers } 919a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 920a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, rsize); 921a8eb96d5SAlan Somers 922a8eb96d5SAlan Somers /* Verify the contents */ 923a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), 924a8eb96d5SAlan Somers "Received data miscompare"); 925a8eb96d5SAlan Somers } 926a8eb96d5SAlan Somers 927a8eb96d5SAlan Somers /* Trying to receive again should return EAGAIN */ 928a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 929a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 930a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 931e594026dSAlan Somers close(sv[0]); 932e594026dSAlan Somers close(sv[1]); 933a8eb96d5SAlan Somers } 934a8eb96d5SAlan Somers 935a8eb96d5SAlan Somers /* 936a8eb96d5SAlan Somers * Simulate the behavior of a blocking pipe. The sender will send until his 937a8eb96d5SAlan Somers * buffer fills up, then we'll simulate a scheduler switch that will allow the 938a8eb96d5SAlan Somers * receiver to read until his buffer empties. Repeat the process until the 939a8eb96d5SAlan Somers * transfer is complete. 940a8eb96d5SAlan Somers * Repeat the test with multiple send and receive buffer sizes 941a8eb96d5SAlan Somers */ 942a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k); 943a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_8k, tc) 944a8eb96d5SAlan Somers { 945a8eb96d5SAlan Somers test_pipe_simulator(8192, 8192); 946a8eb96d5SAlan Somers } 947a8eb96d5SAlan Somers 948a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k); 949a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_128k, tc) 950a8eb96d5SAlan Somers { 951a8eb96d5SAlan Somers test_pipe_simulator(8192, 131072); 952a8eb96d5SAlan Somers } 953a8eb96d5SAlan Somers 954a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k); 955a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_8k, tc) 956a8eb96d5SAlan Somers { 957a8eb96d5SAlan Somers test_pipe_simulator(131072, 8192); 958a8eb96d5SAlan Somers } 959a8eb96d5SAlan Somers 960a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k); 961a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_128k, tc) 962a8eb96d5SAlan Somers { 963a8eb96d5SAlan Somers test_pipe_simulator(131072, 131072); 964a8eb96d5SAlan Somers } 965a8eb96d5SAlan Somers 966a8eb96d5SAlan Somers /* 967a8eb96d5SAlan Somers * Test blocking I/O by passing data between two threads. The total amount of 968a8eb96d5SAlan Somers * data will be >> buffer size to force blocking. Repeat the test with multiple 969a8eb96d5SAlan Somers * send and receive buffer sizes 970a8eb96d5SAlan Somers */ 971a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_8k); 972a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_8k, tc) 973a8eb96d5SAlan Somers { 974a8eb96d5SAlan Somers test_pipe(8192, 8192); 975a8eb96d5SAlan Somers } 976a8eb96d5SAlan Somers 977a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_128k); 978a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_128k, tc) 979a8eb96d5SAlan Somers { 980a8eb96d5SAlan Somers test_pipe(8192, 131072); 981a8eb96d5SAlan Somers } 982a8eb96d5SAlan Somers 983a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_8k); 984a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_8k, tc) 985a8eb96d5SAlan Somers { 986a8eb96d5SAlan Somers test_pipe(131072, 8192); 987a8eb96d5SAlan Somers } 988a8eb96d5SAlan Somers 989a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_128k); 990a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_128k, tc) 991a8eb96d5SAlan Somers { 992a8eb96d5SAlan Somers test_pipe(131072, 131072); 993a8eb96d5SAlan Somers } 994a8eb96d5SAlan Somers 995a8eb96d5SAlan Somers 996a8eb96d5SAlan Somers /* 997a8eb96d5SAlan Somers * Test single-packet I/O with and without blocking, with symmetric buffers of 998a8eb96d5SAlan Somers * various sizes 999a8eb96d5SAlan Somers */ 1000a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k); 1001a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k, tc) 1002a8eb96d5SAlan Somers { 1003a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, true); 1004a8eb96d5SAlan Somers } 1005a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k); 1006a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k, tc) 1007a8eb96d5SAlan Somers { 1008a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, true); 1009a8eb96d5SAlan Somers } 1010a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k); 1011a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k, tc) 1012a8eb96d5SAlan Somers { 1013a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, true); 1014a8eb96d5SAlan Somers } 1015a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k); 1016a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k, tc) 1017a8eb96d5SAlan Somers { 1018a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, true); 1019a8eb96d5SAlan Somers } 1020a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k); 1021a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k, tc) 1022a8eb96d5SAlan Somers { 1023a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, true); 1024a8eb96d5SAlan Somers } 1025a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking); 1026a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k_nonblocking, tc) 1027a8eb96d5SAlan Somers { 1028a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, false); 1029a8eb96d5SAlan Somers } 1030a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking); 1031a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k_nonblocking, tc) 1032a8eb96d5SAlan Somers { 1033a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, false); 1034a8eb96d5SAlan Somers } 1035a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking); 1036a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k_nonblocking, tc) 1037a8eb96d5SAlan Somers { 1038a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, false); 1039a8eb96d5SAlan Somers } 1040a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking); 1041a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k_nonblocking, tc) 1042a8eb96d5SAlan Somers { 1043a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, false); 1044a8eb96d5SAlan Somers } 1045a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking); 1046a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k_nonblocking, tc) 1047a8eb96d5SAlan Somers { 1048a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, false); 1049a8eb96d5SAlan Somers } 1050a8eb96d5SAlan Somers 1051a8eb96d5SAlan Somers 1052a8eb96d5SAlan Somers /* 1053a8eb96d5SAlan Somers * Main. 1054a8eb96d5SAlan Somers */ 1055a8eb96d5SAlan Somers 1056a8eb96d5SAlan Somers ATF_TP_ADD_TCS(tp) 1057a8eb96d5SAlan Somers { 1058a8eb96d5SAlan Somers /* Basic creation and connection tests */ 1059a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socket); 1060a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socketpair); 1061a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_unbound); 1062a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, bind); 1063a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_bound); 1064a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, connect); 1065a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, accept); 1066a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, fcntl_nonblock); 1067a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_buffers); 1068a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_connected_buffers); 1069a8eb96d5SAlan Somers 1070a8eb96d5SAlan Somers /* Unthreaded I/O tests */ 1071a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv); 1072a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_nonblocking); 1073a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_with_connect); 1074a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendto_recvfrom); 1075a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send); 1076a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send_sigpipe); 1077a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_8k); 1078a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_128k); 1079a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_8k); 1080a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_128k); 1081a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k); 1082a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k); 1083a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k); 1084a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k); 1085a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k); 1086a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking); 1087a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking); 1088a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking); 1089a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking); 1090a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking); 1091a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, rcvbuf_oversized); 1092a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k); 1093a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k); 1094a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k); 1095a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k); 1096a8eb96d5SAlan Somers 1097a8eb96d5SAlan Somers /* Threaded I/O tests with blocking sockets */ 1098a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_8k); 1099a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_128k); 1100a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_8k); 1101a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_128k); 1102a8eb96d5SAlan Somers 1103a8eb96d5SAlan Somers return atf_no_error(); 1104a8eb96d5SAlan Somers } 1105