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 __FBSDID("$FreeBSD$"); 27a8eb96d5SAlan Somers 28a8eb96d5SAlan Somers #include <errno.h> 29a8eb96d5SAlan Somers #include <fcntl.h> 30a8eb96d5SAlan Somers #include <pthread.h> 31a8eb96d5SAlan Somers #include <signal.h> 32a8eb96d5SAlan Somers #include <sys/socket.h> 33a8eb96d5SAlan Somers #include <sys/un.h> 34a8eb96d5SAlan Somers 35a8eb96d5SAlan Somers #include <stdio.h> 36a8eb96d5SAlan Somers 37a8eb96d5SAlan Somers #include <atf-c.h> 38a8eb96d5SAlan Somers 39a8eb96d5SAlan Somers /* 40a8eb96d5SAlan Somers * Helper functions 41a8eb96d5SAlan Somers */ 42a8eb96d5SAlan Somers 43a8eb96d5SAlan Somers #define MIN(x, y) ((x) < (y) ? (x) : (y)) 44a8eb96d5SAlan Somers #define MAX(x, y) ((x) > (y) ? (x) : (y)) 45a8eb96d5SAlan Somers 465d5b721aSAlan Somers static void 47a8eb96d5SAlan Somers do_socketpair(int *sv) 48a8eb96d5SAlan Somers { 49a8eb96d5SAlan Somers int s; 50a8eb96d5SAlan Somers 51a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 52a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 53a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] >= 0); 54a8eb96d5SAlan Somers ATF_REQUIRE(sv[1] >= 0); 55a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] != sv[1]); 56a8eb96d5SAlan Somers } 57a8eb96d5SAlan Somers 585d5b721aSAlan Somers static void 59a8eb96d5SAlan Somers do_socketpair_nonblocking(int *sv) 60a8eb96d5SAlan Somers { 61a8eb96d5SAlan Somers int s; 62a8eb96d5SAlan Somers 63a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 64a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 65a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] >= 0); 66a8eb96d5SAlan Somers ATF_REQUIRE(sv[1] >= 0); 67a8eb96d5SAlan Somers ATF_REQUIRE(sv[0] != sv[1]); 68a8eb96d5SAlan Somers ATF_REQUIRE(-1 != fcntl(sv[0], F_SETFL, O_NONBLOCK)); 69a8eb96d5SAlan Somers ATF_REQUIRE(-1 != fcntl(sv[1], F_SETFL, O_NONBLOCK)); 70a8eb96d5SAlan Somers } 71a8eb96d5SAlan Somers 72a8eb96d5SAlan Somers /* 73a8eb96d5SAlan Somers * Returns a pair of sockets made the hard way: bind, listen, connect & accept 74a8eb96d5SAlan Somers * @return const char* The path to the socket 75a8eb96d5SAlan Somers */ 765d5b721aSAlan Somers static const char* 77a8eb96d5SAlan Somers mk_pair_of_sockets(int *sv) 78a8eb96d5SAlan Somers { 79a8eb96d5SAlan Somers struct sockaddr_un sun; 80a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 81a8eb96d5SAlan Somers const char *path = "sock"; 82a8eb96d5SAlan Somers int s, err, s2, s1; 83a8eb96d5SAlan Somers 84a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 85a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 86a8eb96d5SAlan Somers 87a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 88a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 89a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 90a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 91a8eb96d5SAlan Somers err = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 92a8eb96d5SAlan Somers err = listen(s, -1); 93a8eb96d5SAlan Somers ATF_CHECK_EQ(0, err); 94a8eb96d5SAlan Somers ATF_CHECK_EQ(0, err); 95a8eb96d5SAlan Somers 96a8eb96d5SAlan Somers /* Create the other socket */ 97a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 98a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 99a8eb96d5SAlan Somers err = connect(s2, (struct sockaddr*)&sun, sizeof(sun)); 100a8eb96d5SAlan Somers if (err != 0) { 101a8eb96d5SAlan Somers perror("connect"); 102a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 103a8eb96d5SAlan Somers } 104a8eb96d5SAlan Somers 105a8eb96d5SAlan Somers /* Accept it */ 106a8eb96d5SAlan Somers s1 = accept(s, NULL, NULL); 107a8eb96d5SAlan Somers if (s1 == -1) { 108a8eb96d5SAlan Somers perror("accept"); 109a8eb96d5SAlan Somers atf_tc_fail("accept(2) failed"); 110a8eb96d5SAlan Somers } 111a8eb96d5SAlan Somers 112a8eb96d5SAlan Somers sv[0] = s1; 113a8eb96d5SAlan Somers sv[1] = s2; 114a8eb96d5SAlan Somers return (path); 115a8eb96d5SAlan Somers } 116a8eb96d5SAlan Somers 117a8eb96d5SAlan Somers static volatile sig_atomic_t got_sigpipe = 0; 118a8eb96d5SAlan Somers static void 1195d5b721aSAlan Somers shutdown_send_sigpipe_handler(int __unused x) 120a8eb96d5SAlan Somers { 121a8eb96d5SAlan Somers got_sigpipe = 1; 122a8eb96d5SAlan Somers } 123a8eb96d5SAlan Somers 124a8eb96d5SAlan Somers /* 125a8eb96d5SAlan Somers * Parameterized test function bodies 126a8eb96d5SAlan Somers */ 1275d5b721aSAlan Somers static void 128a8eb96d5SAlan Somers test_eagain(size_t sndbufsize, size_t rcvbufsize) 129a8eb96d5SAlan Somers { 130a8eb96d5SAlan Somers int i; 131a8eb96d5SAlan Somers int sv[2]; 132a8eb96d5SAlan Somers const size_t totalsize = (sndbufsize + rcvbufsize) * 2; 133a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 1345d5b721aSAlan Somers const int numpkts = totalsize / pktsize; 135a8eb96d5SAlan Somers char sndbuf[pktsize]; 1365d5b721aSAlan Somers ssize_t ssize; 137a8eb96d5SAlan Somers 138a8eb96d5SAlan Somers /* setup the socket pair */ 139b9a9db10SAlan Somers do_socketpair_nonblocking(sv); 140a8eb96d5SAlan Somers /* Setup the buffers */ 141a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 142a8eb96d5SAlan Somers sizeof(sndbufsize))); 143a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 144a8eb96d5SAlan Somers sizeof(rcvbufsize))); 145a8eb96d5SAlan Somers 146a8eb96d5SAlan Somers bzero(sndbuf, pktsize); 147a8eb96d5SAlan Somers /* Send data until we get EAGAIN */ 1485d5b721aSAlan Somers for(i=0; i < numpkts; i++) { 149a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 150a8eb96d5SAlan Somers if (ssize == -1) { 151a8eb96d5SAlan Somers if (errno == EAGAIN) 152a8eb96d5SAlan Somers atf_tc_pass(); 153a8eb96d5SAlan Somers else { 154a8eb96d5SAlan Somers perror("send"); 155a8eb96d5SAlan Somers atf_tc_fail("send returned < 0 but not EAGAIN"); 156a8eb96d5SAlan Somers } 157a8eb96d5SAlan Somers } 158a8eb96d5SAlan Somers } 159a8eb96d5SAlan Somers atf_tc_fail("Never got EAGAIN"); 160a8eb96d5SAlan Somers } 161a8eb96d5SAlan Somers 1625d5b721aSAlan Somers static void 163a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(size_t bufsize, int blocking) { 164a8eb96d5SAlan Somers int s; 165a8eb96d5SAlan Somers int sv[2]; 1665d5b721aSAlan Somers const ssize_t pktsize = bufsize / 2; 167a8eb96d5SAlan Somers char sndbuf[pktsize]; 168a8eb96d5SAlan Somers char recv_buf[pktsize]; 169a8eb96d5SAlan Somers ssize_t ssize, rsize; 170a8eb96d5SAlan Somers 171a8eb96d5SAlan Somers /* setup the socket pair */ 172a8eb96d5SAlan Somers if (blocking) 173a8eb96d5SAlan Somers do_socketpair(sv); 174a8eb96d5SAlan Somers else 175a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 176a8eb96d5SAlan Somers 177a8eb96d5SAlan Somers /* Setup the buffers */ 178a8eb96d5SAlan Somers s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); 179a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 180a8eb96d5SAlan Somers s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); 181a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 182a8eb96d5SAlan Somers 183a8eb96d5SAlan Somers /* Fill the send buffer */ 184a8eb96d5SAlan Somers bzero(sndbuf, pktsize); 185a8eb96d5SAlan Somers 186a8eb96d5SAlan Somers /* send and receive the packet */ 187a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 188a8eb96d5SAlan Somers if (ssize < 0) { 189a8eb96d5SAlan Somers perror("send"); 190a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 191a8eb96d5SAlan Somers } 192a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd", 193a8eb96d5SAlan Somers pktsize, ssize); 194a8eb96d5SAlan Somers 195a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 196a8eb96d5SAlan Somers if (rsize < 0) { 197a8eb96d5SAlan Somers perror("recv"); 198a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 199a8eb96d5SAlan Somers } 200a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd", 201a8eb96d5SAlan Somers pktsize, rsize); 202a8eb96d5SAlan Somers } 203a8eb96d5SAlan Somers 2045d5b721aSAlan Somers static void 205a8eb96d5SAlan Somers test_pipe_simulator(size_t sndbufsize, size_t rcvbufsize) 206a8eb96d5SAlan Somers { 2075d5b721aSAlan Somers int num_sent, num_received; 208a8eb96d5SAlan Somers int sv[2]; 2095d5b721aSAlan Somers const ssize_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 210a8eb96d5SAlan Somers int numpkts; 211a8eb96d5SAlan Somers char sndbuf[pktsize]; 212a8eb96d5SAlan Somers char rcvbuf[pktsize]; 213a8eb96d5SAlan Somers char comparebuf[pktsize]; 214a8eb96d5SAlan Somers ssize_t ssize, rsize; 215a8eb96d5SAlan Somers bool currently_sending = true; 216a8eb96d5SAlan Somers 217a8eb96d5SAlan Somers /* setup the socket pair */ 218a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 219a8eb96d5SAlan Somers /* Setup the buffers */ 220a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 221a8eb96d5SAlan Somers sizeof(sndbufsize))); 222a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 223a8eb96d5SAlan Somers sizeof(rcvbufsize))); 224a8eb96d5SAlan Somers 225a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 226a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 227a8eb96d5SAlan Somers for (num_sent=0, num_received=0; 228a8eb96d5SAlan Somers num_sent < numpkts || num_received < numpkts; ) { 229a8eb96d5SAlan Somers if (currently_sending && num_sent < numpkts) { 230a8eb96d5SAlan Somers /* The simulated sending process */ 231a8eb96d5SAlan Somers /* fill the buffer */ 232a8eb96d5SAlan Somers memset(sndbuf, num_sent, pktsize); 233a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 234a8eb96d5SAlan Somers if (ssize < 0) { 235a8eb96d5SAlan Somers /* 236a8eb96d5SAlan Somers * XXX: This is bug-compatible with the kernel. 237a8eb96d5SAlan Somers * The kernel returns EMSGSIZE when it should 238a8eb96d5SAlan Somers * return EAGAIN 239a8eb96d5SAlan Somers */ 240a8eb96d5SAlan Somers if (errno == EAGAIN || errno == EMSGSIZE) 241a8eb96d5SAlan Somers currently_sending = false; 242a8eb96d5SAlan Somers else { 243a8eb96d5SAlan Somers perror("send"); 244a8eb96d5SAlan Somers atf_tc_fail("send failed"); 245a8eb96d5SAlan Somers } 246a8eb96d5SAlan Somers } else { 247a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 248a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 249a8eb96d5SAlan Somers pktsize, ssize); 250a8eb96d5SAlan Somers num_sent++; 251a8eb96d5SAlan Somers } 252a8eb96d5SAlan Somers } else { 253a8eb96d5SAlan Somers /* The simulated receiving process */ 254a8eb96d5SAlan Somers rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL); 255a8eb96d5SAlan Somers if (rsize < 0) { 256a8eb96d5SAlan Somers if (errno == EAGAIN) { 257a8eb96d5SAlan Somers currently_sending = true; 258a8eb96d5SAlan Somers ATF_REQUIRE_MSG(num_sent < numpkts, 259a8eb96d5SAlan Somers "Packets were lost!"); 260a8eb96d5SAlan Somers } 261a8eb96d5SAlan Somers else { 262a8eb96d5SAlan Somers perror("recv"); 263a8eb96d5SAlan Somers atf_tc_fail("recv failed"); 264a8eb96d5SAlan Somers } 265a8eb96d5SAlan Somers } else { 266a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 267a8eb96d5SAlan Somers "expected %zd=recv(...) but got %zd", 268a8eb96d5SAlan Somers pktsize, rsize); 269a8eb96d5SAlan Somers memset(comparebuf, num_received, pktsize); 270a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf, 271a8eb96d5SAlan Somers pktsize), 272a8eb96d5SAlan Somers "Received data miscompare"); 273a8eb96d5SAlan Somers num_received++; 274a8eb96d5SAlan Somers } 275a8eb96d5SAlan Somers } 276a8eb96d5SAlan Somers } 277a8eb96d5SAlan Somers } 278a8eb96d5SAlan Somers 279a8eb96d5SAlan Somers typedef struct { 280a8eb96d5SAlan Somers ssize_t pktsize; 281a8eb96d5SAlan Somers int numpkts; 282a8eb96d5SAlan Somers int so; 283a8eb96d5SAlan Somers } test_pipe_thread_data_t; 284a8eb96d5SAlan Somers 285a8eb96d5SAlan Somers static void* 286a8eb96d5SAlan Somers test_pipe_writer(void* args) 287a8eb96d5SAlan Somers { 288a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 289a8eb96d5SAlan Somers char sndbuf[td->pktsize]; 290a8eb96d5SAlan Somers ssize_t ssize; 291a8eb96d5SAlan Somers int i; 292a8eb96d5SAlan Somers 293a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 294a8eb96d5SAlan Somers memset(sndbuf, i, td->pktsize); 295a8eb96d5SAlan Somers ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR); 296a8eb96d5SAlan Somers if (ssize < 0) { 297a8eb96d5SAlan Somers perror("send"); 298a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 299a8eb96d5SAlan Somers } 300a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, ssize, 301a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 302a8eb96d5SAlan Somers td->pktsize, ssize); 303a8eb96d5SAlan Somers } 304a8eb96d5SAlan Somers return (0); 305a8eb96d5SAlan Somers } 306a8eb96d5SAlan Somers 307a8eb96d5SAlan Somers static void* 308a8eb96d5SAlan Somers test_pipe_reader(void* args) 309a8eb96d5SAlan Somers { 310a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 311a8eb96d5SAlan Somers char rcvbuf[td->pktsize]; 312a8eb96d5SAlan Somers char comparebuf[td->pktsize]; 313a8eb96d5SAlan Somers ssize_t rsize; 314a8eb96d5SAlan Somers int i, d; 315a8eb96d5SAlan Somers 316a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 317a8eb96d5SAlan Somers memset(comparebuf, i, td->pktsize); 318a8eb96d5SAlan Somers rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL); 319a8eb96d5SAlan Somers if (rsize < 0) { 320a8eb96d5SAlan Somers perror("recv"); 321a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 322a8eb96d5SAlan Somers } 323a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, rsize, 324a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 325a8eb96d5SAlan Somers td->pktsize, rsize); 326a8eb96d5SAlan Somers d = memcmp(comparebuf, rcvbuf, td->pktsize); 327a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, d, 328a8eb96d5SAlan Somers "Received data miscompare on packet %d", i); 329a8eb96d5SAlan Somers } 330a8eb96d5SAlan Somers return (0); 331a8eb96d5SAlan Somers } 332a8eb96d5SAlan Somers 333a8eb96d5SAlan Somers 3345d5b721aSAlan Somers static void 335a8eb96d5SAlan Somers test_pipe(size_t sndbufsize, size_t rcvbufsize) 336a8eb96d5SAlan Somers { 337a8eb96d5SAlan Somers test_pipe_thread_data_t writer_data, reader_data; 338a8eb96d5SAlan Somers pthread_t writer, reader; 339a8eb96d5SAlan Somers int sv[2]; 340a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 341a8eb96d5SAlan Somers int numpkts; 342a8eb96d5SAlan Somers 343a8eb96d5SAlan Somers /* setup the socket pair */ 344a8eb96d5SAlan Somers do_socketpair(sv); 345a8eb96d5SAlan Somers /* Setup the buffers */ 346a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 347a8eb96d5SAlan Somers sizeof(sndbufsize))); 348a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 349a8eb96d5SAlan Somers sizeof(rcvbufsize))); 350a8eb96d5SAlan Somers 351a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 352a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 353a8eb96d5SAlan Somers 354a8eb96d5SAlan Somers /* Start the child threads */ 355a8eb96d5SAlan Somers writer_data.pktsize = pktsize; 356a8eb96d5SAlan Somers writer_data.numpkts = numpkts; 357a8eb96d5SAlan Somers writer_data.so = sv[0]; 358a8eb96d5SAlan Somers reader_data.pktsize = pktsize; 359a8eb96d5SAlan Somers reader_data.numpkts = numpkts; 360a8eb96d5SAlan Somers reader_data.so = sv[1]; 361a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer, 362a8eb96d5SAlan Somers (void*)&writer_data)); 3638de34a88SAlan Somers /* 3648de34a88SAlan Somers * Give the writer time to start writing, and hopefully block, before 3658de34a88SAlan Somers * starting the reader. This increases the likelihood of the test case 3668de34a88SAlan Somers * failing due to PR kern/185812 3678de34a88SAlan Somers */ 3688de34a88SAlan Somers usleep(1000); 369a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader, 370a8eb96d5SAlan Somers (void*)&reader_data)); 371a8eb96d5SAlan Somers 372a8eb96d5SAlan Somers /* Join the children */ 373a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(writer, NULL)); 374a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(reader, NULL)); 375a8eb96d5SAlan Somers } 376a8eb96d5SAlan Somers 377a8eb96d5SAlan Somers 378a8eb96d5SAlan Somers /* 379a8eb96d5SAlan Somers * Test Cases 380a8eb96d5SAlan Somers */ 381a8eb96d5SAlan Somers 382a8eb96d5SAlan Somers /* Create a SEQPACKET socket */ 383a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socket); 384a8eb96d5SAlan Somers ATF_TC_BODY(create_socket, tc) 385a8eb96d5SAlan Somers { 386a8eb96d5SAlan Somers int s; 387a8eb96d5SAlan Somers 388a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 389a8eb96d5SAlan Somers ATF_CHECK(s >= 0); 390a8eb96d5SAlan Somers } 391a8eb96d5SAlan Somers 392a8eb96d5SAlan Somers /* Create SEQPACKET sockets using socketpair(2) */ 393a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socketpair); 394a8eb96d5SAlan Somers ATF_TC_BODY(create_socketpair, tc) 395a8eb96d5SAlan Somers { 396a8eb96d5SAlan Somers int sv[2]; 397a8eb96d5SAlan Somers int s; 398a8eb96d5SAlan Somers 399a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 400a8eb96d5SAlan Somers ATF_CHECK_EQ(0, s); 401a8eb96d5SAlan Somers ATF_CHECK(sv[0] >= 0); 402a8eb96d5SAlan Somers ATF_CHECK(sv[1] >= 0); 403a8eb96d5SAlan Somers ATF_CHECK(sv[0] != sv[1]); 404a8eb96d5SAlan Somers } 405a8eb96d5SAlan Somers 406a8eb96d5SAlan Somers /* Call listen(2) without first calling bind(2). It should fail */ 407a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_unbound); 408a8eb96d5SAlan Somers ATF_TC_BODY(listen_unbound, tc) 409a8eb96d5SAlan Somers { 410a8eb96d5SAlan Somers int s, r; 411a8eb96d5SAlan Somers 412a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 413a8eb96d5SAlan Somers ATF_REQUIRE(s > 0); 414a8eb96d5SAlan Somers r = listen(s, -1); 415a8eb96d5SAlan Somers /* expect listen to fail since we haven't called bind(2) */ 416a8eb96d5SAlan Somers ATF_CHECK(r != 0); 417a8eb96d5SAlan Somers } 418a8eb96d5SAlan Somers 419a8eb96d5SAlan Somers /* Bind the socket to a file */ 420a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(bind); 421a8eb96d5SAlan Somers ATF_TC_BODY(bind, tc) 422a8eb96d5SAlan Somers { 423a8eb96d5SAlan Somers struct sockaddr_un sun; 424a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 425a8eb96d5SAlan Somers const char *path = "sock"; 426a8eb96d5SAlan Somers int s, r; 427a8eb96d5SAlan Somers 428a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 429a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 430a8eb96d5SAlan Somers 431a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 432a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 433a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 434a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 435a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 436a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 437a8eb96d5SAlan Somers } 438a8eb96d5SAlan Somers 439a8eb96d5SAlan Somers /* listen(2) a socket that is already bound(2) should succeed */ 440a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_bound); 441a8eb96d5SAlan Somers ATF_TC_BODY(listen_bound, tc) 442a8eb96d5SAlan Somers { 443a8eb96d5SAlan Somers struct sockaddr_un sun; 444a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 445a8eb96d5SAlan Somers const char *path = "sock"; 446a8eb96d5SAlan Somers int s, r, l; 447a8eb96d5SAlan Somers 448a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 449a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 450a8eb96d5SAlan Somers 451a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 452a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 453a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 454a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 455a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 456a8eb96d5SAlan Somers l = listen(s, -1); 457a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 458a8eb96d5SAlan Somers ATF_CHECK_EQ(0, l); 459a8eb96d5SAlan Somers } 460a8eb96d5SAlan Somers 461a8eb96d5SAlan Somers /* connect(2) can make a connection */ 462a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(connect); 463a8eb96d5SAlan Somers ATF_TC_BODY(connect, tc) 464a8eb96d5SAlan Somers { 465a8eb96d5SAlan Somers struct sockaddr_un sun; 466a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 467a8eb96d5SAlan Somers const char *path = "sock"; 468a8eb96d5SAlan Somers int s, r, err, l, s2; 469a8eb96d5SAlan Somers 470a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 471a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 472a8eb96d5SAlan Somers 473a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 474a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 475a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 476a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 477a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 478a8eb96d5SAlan Somers l = listen(s, -1); 479a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 480a8eb96d5SAlan Somers ATF_CHECK_EQ(0, l); 481a8eb96d5SAlan Somers 482a8eb96d5SAlan Somers /* Create the other socket */ 483a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 484a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 485a8eb96d5SAlan Somers err = connect(s2, (struct sockaddr*)&sun, sizeof(sun)); 486a8eb96d5SAlan Somers if (err != 0) { 487a8eb96d5SAlan Somers perror("connect"); 488a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 489a8eb96d5SAlan Somers } 490a8eb96d5SAlan Somers } 491a8eb96d5SAlan Somers 492a8eb96d5SAlan Somers /* accept(2) can receive a connection */ 493a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(accept); 494a8eb96d5SAlan Somers ATF_TC_BODY(accept, tc) 495a8eb96d5SAlan Somers { 496a8eb96d5SAlan Somers int sv[2]; 497a8eb96d5SAlan Somers 498a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 499a8eb96d5SAlan Somers } 500a8eb96d5SAlan Somers 501a8eb96d5SAlan Somers 502a8eb96d5SAlan Somers /* Set O_NONBLOCK on the socket */ 503a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(fcntl_nonblock); 504a8eb96d5SAlan Somers ATF_TC_BODY(fcntl_nonblock, tc) 505a8eb96d5SAlan Somers { 506a8eb96d5SAlan Somers int s; 507a8eb96d5SAlan Somers 508a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 509a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 510a8eb96d5SAlan Somers if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) { 511a8eb96d5SAlan Somers perror("fcntl"); 512a8eb96d5SAlan Somers atf_tc_fail("fcntl failed"); 513a8eb96d5SAlan Somers } 514a8eb96d5SAlan Somers } 515a8eb96d5SAlan Somers 516a8eb96d5SAlan Somers /* Resize the send and receive buffers */ 517a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_buffers); 518a8eb96d5SAlan Somers ATF_TC_BODY(resize_buffers, tc) 519a8eb96d5SAlan Somers { 520a8eb96d5SAlan Somers int s; 521a8eb96d5SAlan Somers int sndbuf = 12345; 522a8eb96d5SAlan Somers int rcvbuf = 23456; 523a8eb96d5SAlan Somers int xs, xr; 524a8eb96d5SAlan Somers socklen_t sl = sizeof(xs); 525a8eb96d5SAlan Somers 526a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 527a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 528a8eb96d5SAlan Somers 529a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 530a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF |\n"); 531a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 532a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 533a8eb96d5SAlan Somers printf("Default | %7d | %7d |\n", xs, xr); 534a8eb96d5SAlan Somers 535a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0){ 536a8eb96d5SAlan Somers perror("setsockopt"); 537a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 538a8eb96d5SAlan Somers } 539a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 540a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 541a8eb96d5SAlan Somers printf("After changing SNDBUF | %7d | %7d |\n", xs, xr); 542a8eb96d5SAlan Somers 543a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){ 544a8eb96d5SAlan Somers perror("setsockopt"); 545a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 546a8eb96d5SAlan Somers } 547a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 548a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 549a8eb96d5SAlan Somers printf("After changing RCVBUF | %7d | %7d |\n", xs, xr); 550a8eb96d5SAlan Somers } 551a8eb96d5SAlan Somers 552a8eb96d5SAlan Somers /* 553a8eb96d5SAlan Somers * Resize the send and receive buffers of a connected socketpair 554a8eb96d5SAlan Somers * Print some useful debugging info too 555a8eb96d5SAlan Somers */ 556a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_connected_buffers); 557a8eb96d5SAlan Somers ATF_TC_BODY(resize_connected_buffers, tc) 558a8eb96d5SAlan Somers { 559a8eb96d5SAlan Somers int sv[2]; 560a8eb96d5SAlan Somers int sndbuf = 12345; 561a8eb96d5SAlan Somers int rcvbuf = 23456; 562a8eb96d5SAlan Somers int err; 563a8eb96d5SAlan Somers int ls, lr, rs, rr; 564a8eb96d5SAlan Somers socklen_t sl = sizeof(ls); 565a8eb96d5SAlan Somers 566a8eb96d5SAlan Somers /* setup the socket pair */ 567a8eb96d5SAlan Somers do_socketpair(sv); 568a8eb96d5SAlan Somers 569a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 570a8eb96d5SAlan Somers printf(" | Left Socket | Right Socket |\n"); 571a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF | SNDBUF | RCVBUF |\n"); 572a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 573a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 574a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 575a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 576a8eb96d5SAlan Somers printf("Default | %7d | %7d | %7d | %7d |\n", 577a8eb96d5SAlan Somers ls, lr, rs, rr); 578a8eb96d5SAlan Somers 579a8eb96d5SAlan Somers /* Update one side's send buffer */ 580a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 581a8eb96d5SAlan Somers if (err != 0){ 582a8eb96d5SAlan Somers perror("setsockopt"); 583a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 584a8eb96d5SAlan Somers } 585a8eb96d5SAlan Somers 586a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 587a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 588a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 589a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 590a8eb96d5SAlan Somers printf("After changing Left's SNDBUF | %7d | %7d | %7d | %7d |\n", 591a8eb96d5SAlan Somers ls, lr, rs, rr); 592a8eb96d5SAlan Somers 593a8eb96d5SAlan Somers /* Update the same side's receive buffer */ 594a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); 595a8eb96d5SAlan Somers if (err != 0){ 596a8eb96d5SAlan Somers perror("setsockopt"); 597a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 598a8eb96d5SAlan Somers } 599a8eb96d5SAlan Somers 600a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 601a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 602a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 603a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 604a8eb96d5SAlan Somers printf("After changing Left's RCVBUF | %7d | %7d | %7d | %7d |\n", 605a8eb96d5SAlan Somers ls, lr, rs, rr); 606a8eb96d5SAlan Somers } 607a8eb96d5SAlan Somers 608a8eb96d5SAlan Somers 609a8eb96d5SAlan Somers /* send(2) and recv(2) a single short record */ 610a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv); 611a8eb96d5SAlan Somers ATF_TC_BODY(send_recv, tc) 612a8eb96d5SAlan Somers { 613a8eb96d5SAlan Somers int sv[2]; 614a8eb96d5SAlan Somers const int bufsize = 64; 615a8eb96d5SAlan Somers const char *data = "data"; 616a8eb96d5SAlan Somers char recv_buf[bufsize]; 6175d5b721aSAlan Somers ssize_t datalen; 618a8eb96d5SAlan Somers ssize_t ssize, rsize; 619a8eb96d5SAlan Somers 620a8eb96d5SAlan Somers /* setup the socket pair */ 621a8eb96d5SAlan Somers do_socketpair(sv); 622a8eb96d5SAlan Somers 623a8eb96d5SAlan Somers /* send and receive a small packet */ 624a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 625a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 626a8eb96d5SAlan Somers if (ssize < 0) { 627a8eb96d5SAlan Somers perror("send"); 628a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 629a8eb96d5SAlan Somers } 630a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 631a8eb96d5SAlan Somers datalen, ssize); 632a8eb96d5SAlan Somers 633a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 634a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 635a8eb96d5SAlan Somers } 636a8eb96d5SAlan Somers 637a8eb96d5SAlan Somers /* sendto(2) and recvfrom(2) a single short record 638a8eb96d5SAlan Somers * According to The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 639a8eb96d5SAlan Somers * Edition, sendto(2) is exactly the same as send(2) on a connection-mode socket 640a8eb96d5SAlan Somers * 641a8eb96d5SAlan Somers * According to the same spec, not all protocols are required to provide the 642a8eb96d5SAlan Somers * source addres in recvfrom(2). 643a8eb96d5SAlan Somers */ 644a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendto_recvfrom); 645a8eb96d5SAlan Somers ATF_TC_BODY(sendto_recvfrom, tc) 646a8eb96d5SAlan Somers { 647a8eb96d5SAlan Somers const char* path; 648a8eb96d5SAlan Somers struct sockaddr_storage from; 649a8eb96d5SAlan Somers int sv[2]; 650a8eb96d5SAlan Somers const int bufsize = 64; 651a8eb96d5SAlan Somers const char *data = "data"; 652a8eb96d5SAlan Somers char recv_buf[bufsize]; 6535d5b721aSAlan Somers ssize_t datalen; 654a8eb96d5SAlan Somers ssize_t ssize, rsize; 655a8eb96d5SAlan Somers socklen_t fromlen; 656a8eb96d5SAlan Somers 657a8eb96d5SAlan Somers /* setup the socket pair */ 658a8eb96d5SAlan Somers path = mk_pair_of_sockets(sv); 659a8eb96d5SAlan Somers 660a8eb96d5SAlan Somers /* send and receive a small packet */ 661a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 662a8eb96d5SAlan Somers ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0); 663a8eb96d5SAlan Somers if (ssize < 0) { 664a8eb96d5SAlan Somers perror("send"); 665a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 666a8eb96d5SAlan Somers } 667a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 668a8eb96d5SAlan Somers datalen, ssize); 669a8eb96d5SAlan Somers 670a8eb96d5SAlan Somers fromlen = sizeof(from); 671a8eb96d5SAlan Somers rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL, 672a8eb96d5SAlan Somers (struct sockaddr*)&from, &fromlen); 673a8eb96d5SAlan Somers if (ssize < 0) { 674a8eb96d5SAlan Somers perror("recvfrom"); 675a8eb96d5SAlan Somers atf_tc_fail("recvfrom returned < 0"); 676a8eb96d5SAlan Somers } 677a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 678a8eb96d5SAlan Somers 679a8eb96d5SAlan Somers /* 680a8eb96d5SAlan Somers * FreeBSD does not currently provide the source address for SEQ_PACKET 681a8eb96d5SAlan Somers * AF_UNIX sockets, and POSIX does not require it, so these two checks 682a8eb96d5SAlan Somers * are disabled. If FreeBSD gains that feature in the future, then 683a8eb96d5SAlan Somers * these checks may be reenabled 684a8eb96d5SAlan Somers */ 685a8eb96d5SAlan Somers /* ATF_CHECK_EQ(PF_LOCAL, from.ss_family); */ 686a8eb96d5SAlan Somers /* ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path); */ 687a8eb96d5SAlan Somers } 688a8eb96d5SAlan Somers 689a8eb96d5SAlan Somers /* 690a8eb96d5SAlan Somers * send(2) and recv(2) a single short record with sockets created the 691a8eb96d5SAlan Somers * traditional way, involving bind, listen, connect, and accept 692a8eb96d5SAlan Somers */ 693a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_with_connect); 694a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_with_connect, tc) 695a8eb96d5SAlan Somers { 696a8eb96d5SAlan Somers int sv[2]; 697a8eb96d5SAlan Somers const int bufsize = 64; 698a8eb96d5SAlan Somers const char *data = "data"; 699a8eb96d5SAlan Somers char recv_buf[bufsize]; 7005d5b721aSAlan Somers ssize_t datalen; 701a8eb96d5SAlan Somers ssize_t ssize, rsize; 702a8eb96d5SAlan Somers 703a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 704a8eb96d5SAlan Somers 705a8eb96d5SAlan Somers /* send and receive a small packet */ 706a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 707a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 708a8eb96d5SAlan Somers if (ssize < 0) { 709a8eb96d5SAlan Somers perror("send"); 710a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 711a8eb96d5SAlan Somers } 712a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 713a8eb96d5SAlan Somers datalen, ssize); 714a8eb96d5SAlan Somers 715a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 716a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 717a8eb96d5SAlan Somers } 718a8eb96d5SAlan Somers 719a8eb96d5SAlan Somers /* send(2) should fail on a shutdown socket */ 720a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send); 721a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send, tc) 722a8eb96d5SAlan Somers { 723a8eb96d5SAlan Somers int s; 724a8eb96d5SAlan Somers const char *data = "data"; 725a8eb96d5SAlan Somers ssize_t ssize; 726a8eb96d5SAlan Somers 727a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 728a8eb96d5SAlan Somers ATF_CHECK(s >= 0); 729a8eb96d5SAlan Somers ATF_CHECK_EQ(0, shutdown(s, SHUT_RDWR)); 730a8eb96d5SAlan Somers /* USE MSG_NOSIGNAL so we don't get SIGPIPE */ 731a8eb96d5SAlan Somers ssize = send(s, data, sizeof(data), MSG_EOR | MSG_NOSIGNAL); 732a8eb96d5SAlan Somers ATF_CHECK_EQ(EPIPE, errno); 733a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 734a8eb96d5SAlan Somers } 735a8eb96d5SAlan Somers 736a8eb96d5SAlan Somers /* send(2) should cause SIGPIPE on a shutdown socket */ 737a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe); 738a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send_sigpipe, tc) 739a8eb96d5SAlan Somers { 740a8eb96d5SAlan Somers int s; 741a8eb96d5SAlan Somers const char *data = "data"; 742a8eb96d5SAlan Somers ssize_t ssize; 743a8eb96d5SAlan Somers 744a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 745a8eb96d5SAlan Somers ATF_CHECK(s >= 0); 746a8eb96d5SAlan Somers ATF_CHECK_EQ(0, shutdown(s, SHUT_RDWR)); 747a8eb96d5SAlan Somers ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); 748a8eb96d5SAlan Somers ssize = send(s, data, sizeof(data), MSG_EOR); 749a8eb96d5SAlan Somers ATF_CHECK_EQ(1, got_sigpipe); 750a8eb96d5SAlan Somers } 751a8eb96d5SAlan Somers 752a8eb96d5SAlan Somers /* nonblocking send(2) and recv(2) a single short record */ 753a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 754a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_nonblocking, tc) 755a8eb96d5SAlan Somers { 756a8eb96d5SAlan Somers int sv[2]; 757a8eb96d5SAlan Somers const int bufsize = 64; 758a8eb96d5SAlan Somers const char *data = "data"; 759a8eb96d5SAlan Somers char recv_buf[bufsize]; 7605d5b721aSAlan Somers ssize_t datalen; 761a8eb96d5SAlan Somers ssize_t ssize, rsize; 762a8eb96d5SAlan Somers 763a8eb96d5SAlan Somers /* setup the socket pair */ 764a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 765a8eb96d5SAlan Somers 766a8eb96d5SAlan Somers /* Verify that there is nothing to receive */ 767a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 768a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 769a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 770a8eb96d5SAlan Somers 771a8eb96d5SAlan Somers /* send and receive a small packet */ 772a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 773a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 774a8eb96d5SAlan Somers if (ssize < 0) { 775a8eb96d5SAlan Somers perror("send"); 776a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 777a8eb96d5SAlan Somers } 778a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 779a8eb96d5SAlan Somers datalen, ssize); 780a8eb96d5SAlan Somers 781a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 782a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 783a8eb96d5SAlan Somers } 784a8eb96d5SAlan Somers 785a8eb96d5SAlan Somers /* 786a8eb96d5SAlan Somers * We should get EMSGSIZE if we try to send a message larger than the socket 787a8eb96d5SAlan Somers * buffer, with blocking sockets 788a8eb96d5SAlan Somers */ 789a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(emsgsize); 790a8eb96d5SAlan Somers ATF_TC_BODY(emsgsize, tc) 791a8eb96d5SAlan Somers { 792a8eb96d5SAlan Somers int sv[2]; 793a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 794a8eb96d5SAlan Somers const size_t rcvbufsize = 8192; 795a8eb96d5SAlan Somers const size_t pktsize = (sndbufsize + rcvbufsize) * 2; 796a8eb96d5SAlan Somers char sndbuf[pktsize]; 7975d5b721aSAlan Somers ssize_t ssize; 798a8eb96d5SAlan Somers 799a8eb96d5SAlan Somers /* setup the socket pair */ 800a8eb96d5SAlan Somers do_socketpair(sv); 801a8eb96d5SAlan Somers /* Setup the buffers */ 802a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 803a8eb96d5SAlan Somers sizeof(sndbufsize))); 804a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 805a8eb96d5SAlan Somers sizeof(rcvbufsize))); 806a8eb96d5SAlan Somers 807a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 808a8eb96d5SAlan Somers ATF_CHECK_EQ(EMSGSIZE, errno); 809a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 810a8eb96d5SAlan Somers } 811a8eb96d5SAlan Somers 812a8eb96d5SAlan Somers /* 813a8eb96d5SAlan Somers * We should get EMSGSIZE if we try to send a message larger than the socket 814a8eb96d5SAlan Somers * buffer, with nonblocking sockets 815a8eb96d5SAlan Somers */ 816a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(emsgsize_nonblocking); 817a8eb96d5SAlan Somers ATF_TC_BODY(emsgsize_nonblocking, tc) 818a8eb96d5SAlan Somers { 819a8eb96d5SAlan Somers int sv[2]; 820a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 821a8eb96d5SAlan Somers const size_t rcvbufsize = 8192; 822a8eb96d5SAlan Somers const size_t pktsize = (sndbufsize + rcvbufsize) * 2; 823a8eb96d5SAlan Somers char sndbuf[pktsize]; 8245d5b721aSAlan Somers ssize_t ssize; 825a8eb96d5SAlan Somers 826a8eb96d5SAlan Somers /* setup the socket pair */ 827a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 828a8eb96d5SAlan Somers /* Setup the buffers */ 829a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 830a8eb96d5SAlan Somers sizeof(sndbufsize))); 831a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 832a8eb96d5SAlan Somers sizeof(rcvbufsize))); 833a8eb96d5SAlan Somers 834a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 835a8eb96d5SAlan Somers ATF_CHECK_EQ(EMSGSIZE, errno); 836a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 837a8eb96d5SAlan Somers } 838a8eb96d5SAlan Somers 839a8eb96d5SAlan Somers 840a8eb96d5SAlan Somers /* 841a8eb96d5SAlan Somers * We should get EAGAIN if we try to send a message larger than the socket 842a8eb96d5SAlan Somers * buffer, with nonblocking sockets. Test with several different sockbuf sizes 843a8eb96d5SAlan Somers */ 844a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_8k); 845a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_8k, tc) 846a8eb96d5SAlan Somers { 847a8eb96d5SAlan Somers atf_tc_expect_fail("PR kern/185812 send(2) on a UNIX domain SEQPACKET socket returns EMSGSIZE instead of EAGAIN"); 848a8eb96d5SAlan Somers test_eagain(8192, 8192); 849a8eb96d5SAlan Somers } 850a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_128k); 851a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_128k, tc) 852a8eb96d5SAlan Somers { 853a8eb96d5SAlan Somers atf_tc_expect_fail("PR kern/185812 send(2) on a UNIX domain SEQPACKET socket returns EMSGSIZE instead of EAGAIN"); 854a8eb96d5SAlan Somers test_eagain(8192, 131072); 855a8eb96d5SAlan Somers } 856a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_8k); 857a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_8k, tc) 858a8eb96d5SAlan Somers { 859a8eb96d5SAlan Somers atf_tc_expect_fail("PR kern/185812 send(2) on a UNIX domain SEQPACKET socket returns EMSGSIZE instead of EAGAIN"); 860a8eb96d5SAlan Somers test_eagain(131072, 8192); 861a8eb96d5SAlan Somers } 862a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_128k); 863a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_128k, tc) 864a8eb96d5SAlan Somers { 865a8eb96d5SAlan Somers atf_tc_expect_fail("PR kern/185812 send(2) on a UNIX domain SEQPACKET socket returns EMSGSIZE instead of EAGAIN"); 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]; 8795d5b721aSAlan Somers const int pktsize = 1024; 880a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 881a8eb96d5SAlan Somers const size_t 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); 931a8eb96d5SAlan Somers } 932a8eb96d5SAlan Somers 933a8eb96d5SAlan Somers /* 934a8eb96d5SAlan Somers * Simulate the behavior of a blocking pipe. The sender will send until his 935a8eb96d5SAlan Somers * buffer fills up, then we'll simulate a scheduler switch that will allow the 936a8eb96d5SAlan Somers * receiver to read until his buffer empties. Repeat the process until the 937a8eb96d5SAlan Somers * transfer is complete. 938a8eb96d5SAlan Somers * Repeat the test with multiple send and receive buffer sizes 939a8eb96d5SAlan Somers */ 940a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k); 941a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_8k, tc) 942a8eb96d5SAlan Somers { 943a8eb96d5SAlan Somers test_pipe_simulator(8192, 8192); 944a8eb96d5SAlan Somers } 945a8eb96d5SAlan Somers 946a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k); 947a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_128k, tc) 948a8eb96d5SAlan Somers { 949a8eb96d5SAlan Somers test_pipe_simulator(8192, 131072); 950a8eb96d5SAlan Somers } 951a8eb96d5SAlan Somers 952a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k); 953a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_8k, tc) 954a8eb96d5SAlan Somers { 955a8eb96d5SAlan Somers test_pipe_simulator(131072, 8192); 956a8eb96d5SAlan Somers } 957a8eb96d5SAlan Somers 958a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k); 959a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_128k, tc) 960a8eb96d5SAlan Somers { 961a8eb96d5SAlan Somers test_pipe_simulator(131072, 131072); 962a8eb96d5SAlan Somers } 963a8eb96d5SAlan Somers 964a8eb96d5SAlan Somers /* 965a8eb96d5SAlan Somers * Test blocking I/O by passing data between two threads. The total amount of 966a8eb96d5SAlan Somers * data will be >> buffer size to force blocking. Repeat the test with multiple 967a8eb96d5SAlan Somers * send and receive buffer sizes 968a8eb96d5SAlan Somers */ 969a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_8k); 970a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_8k, tc) 971a8eb96d5SAlan Somers { 972a8eb96d5SAlan Somers atf_tc_expect_fail("PR kern/185812 send(2) on a UNIX domain SEQPACKET socket returns EMSGSIZE instead of EAGAIN"); 973a8eb96d5SAlan Somers test_pipe(8192, 8192); 974a8eb96d5SAlan Somers } 975a8eb96d5SAlan Somers 976a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_128k); 977a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_128k, tc) 978a8eb96d5SAlan Somers { 979a8eb96d5SAlan Somers atf_tc_expect_fail("PR kern/185812 send(2) on a UNIX domain SEQPACKET socket returns EMSGSIZE instead of EAGAIN"); 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 /* 987a8eb96d5SAlan Somers * kern/185812 causes this test case to both fail and timeout. The 988a8eb96d5SAlan Somers * atf-c-api(3) doesn't have a way to set such an expectation. 989a8eb96d5SAlan Somers * If you use atf_tc_expect_fail, then it will timeout. If you use 990a8eb96d5SAlan Somers * atf_tc_expect_timeout, then it will fail. If you use both, then it 991a8eb96d5SAlan Somers * will show up as an unexpected pass, which is much worse 992a8eb96d5SAlan Somers * 993a8eb96d5SAlan Somers * https://code.google.com/p/kyua/issues/detail?id=76 994a8eb96d5SAlan Somers */ 995a8eb96d5SAlan Somers atf_tc_expect_fail("PR kern/185812 send(2) on a UNIX domain SEQPACKET socket returns EMSGSIZE instead of EAGAIN"); 996a8eb96d5SAlan Somers test_pipe(131072, 8192); 997a8eb96d5SAlan Somers } 998a8eb96d5SAlan Somers 999a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_128k); 1000a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_128k, tc) 1001a8eb96d5SAlan Somers { 1002a8eb96d5SAlan Somers atf_tc_expect_fail("PR kern/185812 send(2) on a UNIX domain SEQPACKET socket returns EMSGSIZE instead of EAGAIN"); 1003a8eb96d5SAlan Somers test_pipe(131072, 131072); 1004a8eb96d5SAlan Somers } 1005a8eb96d5SAlan Somers 1006a8eb96d5SAlan Somers 1007a8eb96d5SAlan Somers /* 1008a8eb96d5SAlan Somers * Test single-packet I/O with and without blocking, with symmetric buffers of 1009a8eb96d5SAlan Somers * various sizes 1010a8eb96d5SAlan Somers */ 1011a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k); 1012a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k, tc) 1013a8eb96d5SAlan Somers { 1014a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, true); 1015a8eb96d5SAlan Somers } 1016a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k); 1017a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k, tc) 1018a8eb96d5SAlan Somers { 1019a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, true); 1020a8eb96d5SAlan Somers } 1021a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k); 1022a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k, tc) 1023a8eb96d5SAlan Somers { 1024a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, true); 1025a8eb96d5SAlan Somers } 1026a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k); 1027a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k, tc) 1028a8eb96d5SAlan Somers { 1029a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, true); 1030a8eb96d5SAlan Somers } 1031a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k); 1032a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k, tc) 1033a8eb96d5SAlan Somers { 1034a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, true); 1035a8eb96d5SAlan Somers } 1036a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking); 1037a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k_nonblocking, tc) 1038a8eb96d5SAlan Somers { 1039a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, false); 1040a8eb96d5SAlan Somers } 1041a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking); 1042a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k_nonblocking, tc) 1043a8eb96d5SAlan Somers { 1044a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, false); 1045a8eb96d5SAlan Somers } 1046a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking); 1047a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k_nonblocking, tc) 1048a8eb96d5SAlan Somers { 1049a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, false); 1050a8eb96d5SAlan Somers } 1051a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking); 1052a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k_nonblocking, tc) 1053a8eb96d5SAlan Somers { 1054a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, false); 1055a8eb96d5SAlan Somers } 1056a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking); 1057a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k_nonblocking, tc) 1058a8eb96d5SAlan Somers { 1059a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, false); 1060a8eb96d5SAlan Somers } 1061a8eb96d5SAlan Somers 1062a8eb96d5SAlan Somers 1063a8eb96d5SAlan Somers /* 1064a8eb96d5SAlan Somers * Main. 1065a8eb96d5SAlan Somers */ 1066a8eb96d5SAlan Somers 1067a8eb96d5SAlan Somers ATF_TP_ADD_TCS(tp) 1068a8eb96d5SAlan Somers { 1069a8eb96d5SAlan Somers /* Basic creation and connection tests */ 1070a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socket); 1071a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socketpair); 1072a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_unbound); 1073a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, bind); 1074a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_bound); 1075a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, connect); 1076a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, accept); 1077a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, fcntl_nonblock); 1078a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_buffers); 1079a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_connected_buffers); 1080a8eb96d5SAlan Somers 1081a8eb96d5SAlan Somers /* Unthreaded I/O tests */ 1082a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv); 1083a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_nonblocking); 1084a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_with_connect); 1085a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendto_recvfrom); 1086a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send); 1087a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send_sigpipe); 1088a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, emsgsize); 1089a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, emsgsize_nonblocking); 1090a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_8k); 1091a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_128k); 1092a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_8k); 1093a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_128k); 1094a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k); 1095a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k); 1096a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k); 1097a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k); 1098a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k); 1099a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking); 1100a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking); 1101a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking); 1102a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking); 1103a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking); 1104a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, rcvbuf_oversized); 1105a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k); 1106a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k); 1107a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k); 1108a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k); 1109a8eb96d5SAlan Somers 1110a8eb96d5SAlan Somers /* Threaded I/O tests with blocking sockets */ 1111a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_8k); 1112a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_128k); 1113a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_8k); 1114a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_128k); 1115a8eb96d5SAlan Somers 1116a8eb96d5SAlan Somers return atf_no_error(); 1117a8eb96d5SAlan Somers } 1118