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 95a8eb96d5SAlan Somers /* Create the other socket */ 96a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 97a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 98a8eb96d5SAlan Somers err = connect(s2, (struct sockaddr*)&sun, sizeof(sun)); 99a8eb96d5SAlan Somers if (err != 0) { 100a8eb96d5SAlan Somers perror("connect"); 101a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 102a8eb96d5SAlan Somers } 103a8eb96d5SAlan Somers 104a8eb96d5SAlan Somers /* Accept it */ 105a8eb96d5SAlan Somers s1 = accept(s, NULL, NULL); 106a8eb96d5SAlan Somers if (s1 == -1) { 107a8eb96d5SAlan Somers perror("accept"); 108a8eb96d5SAlan Somers atf_tc_fail("accept(2) failed"); 109a8eb96d5SAlan Somers } 110a8eb96d5SAlan Somers 111a8eb96d5SAlan Somers sv[0] = s1; 112a8eb96d5SAlan Somers sv[1] = s2; 113e594026dSAlan Somers 114e594026dSAlan Somers close(s); 115e594026dSAlan Somers 116a8eb96d5SAlan Somers return (path); 117a8eb96d5SAlan Somers } 118a8eb96d5SAlan Somers 119a8eb96d5SAlan Somers static volatile sig_atomic_t got_sigpipe = 0; 120a8eb96d5SAlan Somers static void 1215d5b721aSAlan Somers shutdown_send_sigpipe_handler(int __unused x) 122a8eb96d5SAlan Somers { 123a8eb96d5SAlan Somers got_sigpipe = 1; 124a8eb96d5SAlan Somers } 125a8eb96d5SAlan Somers 126a8eb96d5SAlan Somers /* 127a8eb96d5SAlan Somers * Parameterized test function bodies 128a8eb96d5SAlan Somers */ 1295d5b721aSAlan Somers static void 130a8eb96d5SAlan Somers test_eagain(size_t sndbufsize, size_t rcvbufsize) 131a8eb96d5SAlan Somers { 132a8eb96d5SAlan Somers int i; 133a8eb96d5SAlan Somers int sv[2]; 134a8eb96d5SAlan Somers const size_t totalsize = (sndbufsize + rcvbufsize) * 2; 135a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 1365d5b721aSAlan Somers const int numpkts = totalsize / pktsize; 137a8eb96d5SAlan Somers char sndbuf[pktsize]; 1385d5b721aSAlan Somers ssize_t ssize; 139a8eb96d5SAlan Somers 140a8eb96d5SAlan Somers /* setup the socket pair */ 141b9a9db10SAlan Somers do_socketpair_nonblocking(sv); 142a8eb96d5SAlan Somers /* Setup the buffers */ 143a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 144a8eb96d5SAlan Somers sizeof(sndbufsize))); 145a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 146a8eb96d5SAlan Somers sizeof(rcvbufsize))); 147a8eb96d5SAlan Somers 148a8eb96d5SAlan Somers bzero(sndbuf, pktsize); 149a8eb96d5SAlan Somers /* Send data until we get EAGAIN */ 1505d5b721aSAlan Somers for(i=0; i < numpkts; i++) { 151a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 152a8eb96d5SAlan Somers if (ssize == -1) { 153e594026dSAlan Somers if (errno == EAGAIN) { 154e594026dSAlan Somers close(sv[0]); 155e594026dSAlan Somers close(sv[1]); 156a8eb96d5SAlan Somers atf_tc_pass(); 157e594026dSAlan Somers } 158a8eb96d5SAlan Somers else { 159a8eb96d5SAlan Somers perror("send"); 160a8eb96d5SAlan Somers atf_tc_fail("send returned < 0 but not EAGAIN"); 161a8eb96d5SAlan Somers } 162a8eb96d5SAlan Somers } 163a8eb96d5SAlan Somers } 164a8eb96d5SAlan Somers atf_tc_fail("Never got EAGAIN"); 165a8eb96d5SAlan Somers } 166a8eb96d5SAlan Somers 1675d5b721aSAlan Somers static void 168a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(size_t bufsize, int blocking) { 169a8eb96d5SAlan Somers int s; 170a8eb96d5SAlan Somers int sv[2]; 1715d5b721aSAlan Somers const ssize_t pktsize = bufsize / 2; 172a8eb96d5SAlan Somers char sndbuf[pktsize]; 173a8eb96d5SAlan Somers char recv_buf[pktsize]; 174a8eb96d5SAlan Somers ssize_t ssize, rsize; 175a8eb96d5SAlan Somers 176a8eb96d5SAlan Somers /* setup the socket pair */ 177a8eb96d5SAlan Somers if (blocking) 178a8eb96d5SAlan Somers do_socketpair(sv); 179a8eb96d5SAlan Somers else 180a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 181a8eb96d5SAlan Somers 182a8eb96d5SAlan Somers /* Setup the buffers */ 183a8eb96d5SAlan Somers s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); 184a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 185a8eb96d5SAlan Somers s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); 186a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, s); 187a8eb96d5SAlan Somers 188a8eb96d5SAlan Somers /* Fill the send buffer */ 189a8eb96d5SAlan Somers bzero(sndbuf, pktsize); 190a8eb96d5SAlan Somers 191a8eb96d5SAlan Somers /* send and receive the packet */ 192a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 193a8eb96d5SAlan Somers if (ssize < 0) { 194a8eb96d5SAlan Somers perror("send"); 195a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 196a8eb96d5SAlan Somers } 197a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd", 198a8eb96d5SAlan Somers pktsize, ssize); 199a8eb96d5SAlan Somers 200a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 201a8eb96d5SAlan Somers if (rsize < 0) { 202a8eb96d5SAlan Somers perror("recv"); 203a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 204a8eb96d5SAlan Somers } 205a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd", 206a8eb96d5SAlan Somers pktsize, rsize); 207e594026dSAlan Somers close(sv[0]); 208e594026dSAlan Somers close(sv[1]); 209a8eb96d5SAlan Somers } 210a8eb96d5SAlan Somers 2115d5b721aSAlan Somers static void 212a8eb96d5SAlan Somers test_pipe_simulator(size_t sndbufsize, size_t rcvbufsize) 213a8eb96d5SAlan Somers { 2145d5b721aSAlan Somers int num_sent, num_received; 215a8eb96d5SAlan Somers int sv[2]; 2165d5b721aSAlan Somers const ssize_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 217a8eb96d5SAlan Somers int numpkts; 218a8eb96d5SAlan Somers char sndbuf[pktsize]; 219a8eb96d5SAlan Somers char rcvbuf[pktsize]; 220a8eb96d5SAlan Somers char comparebuf[pktsize]; 221a8eb96d5SAlan Somers ssize_t ssize, rsize; 222a8eb96d5SAlan Somers bool currently_sending = true; 223a8eb96d5SAlan Somers 224a8eb96d5SAlan Somers /* setup the socket pair */ 225a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 226a8eb96d5SAlan Somers /* Setup the buffers */ 227a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 228a8eb96d5SAlan Somers sizeof(sndbufsize))); 229a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 230a8eb96d5SAlan Somers sizeof(rcvbufsize))); 231a8eb96d5SAlan Somers 232a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 233a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 234a8eb96d5SAlan Somers for (num_sent=0, num_received=0; 235a8eb96d5SAlan Somers num_sent < numpkts || num_received < numpkts; ) { 236a8eb96d5SAlan Somers if (currently_sending && num_sent < numpkts) { 237a8eb96d5SAlan Somers /* The simulated sending process */ 238a8eb96d5SAlan Somers /* fill the buffer */ 239a8eb96d5SAlan Somers memset(sndbuf, num_sent, pktsize); 240a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 241a8eb96d5SAlan Somers if (ssize < 0) { 242a8eb96d5SAlan Somers /* 243a8eb96d5SAlan Somers * XXX: This is bug-compatible with the kernel. 244a8eb96d5SAlan Somers * The kernel returns EMSGSIZE when it should 245a8eb96d5SAlan Somers * return EAGAIN 246a8eb96d5SAlan Somers */ 247a8eb96d5SAlan Somers if (errno == EAGAIN || errno == EMSGSIZE) 248a8eb96d5SAlan Somers currently_sending = false; 249a8eb96d5SAlan Somers else { 250a8eb96d5SAlan Somers perror("send"); 251a8eb96d5SAlan Somers atf_tc_fail("send failed"); 252a8eb96d5SAlan Somers } 253a8eb96d5SAlan Somers } else { 254a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 255a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 256a8eb96d5SAlan Somers pktsize, ssize); 257a8eb96d5SAlan Somers num_sent++; 258a8eb96d5SAlan Somers } 259a8eb96d5SAlan Somers } else { 260a8eb96d5SAlan Somers /* The simulated receiving process */ 261a8eb96d5SAlan Somers rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL); 262a8eb96d5SAlan Somers if (rsize < 0) { 263a8eb96d5SAlan Somers if (errno == EAGAIN) { 264a8eb96d5SAlan Somers currently_sending = true; 265a8eb96d5SAlan Somers ATF_REQUIRE_MSG(num_sent < numpkts, 266a8eb96d5SAlan Somers "Packets were lost!"); 267a8eb96d5SAlan Somers } 268a8eb96d5SAlan Somers else { 269a8eb96d5SAlan Somers perror("recv"); 270a8eb96d5SAlan Somers atf_tc_fail("recv failed"); 271a8eb96d5SAlan Somers } 272a8eb96d5SAlan Somers } else { 273a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 274a8eb96d5SAlan Somers "expected %zd=recv(...) but got %zd", 275a8eb96d5SAlan Somers pktsize, rsize); 276a8eb96d5SAlan Somers memset(comparebuf, num_received, pktsize); 277a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf, 278a8eb96d5SAlan Somers pktsize), 279a8eb96d5SAlan Somers "Received data miscompare"); 280a8eb96d5SAlan Somers num_received++; 281a8eb96d5SAlan Somers } 282a8eb96d5SAlan Somers } 283a8eb96d5SAlan Somers } 284e594026dSAlan Somers close(sv[0]); 285e594026dSAlan Somers close(sv[1]); 286a8eb96d5SAlan Somers } 287a8eb96d5SAlan Somers 288a8eb96d5SAlan Somers typedef struct { 289a8eb96d5SAlan Somers ssize_t pktsize; 290a8eb96d5SAlan Somers int numpkts; 291a8eb96d5SAlan Somers int so; 292a8eb96d5SAlan Somers } test_pipe_thread_data_t; 293a8eb96d5SAlan Somers 294a8eb96d5SAlan Somers static void* 295a8eb96d5SAlan Somers test_pipe_writer(void* args) 296a8eb96d5SAlan Somers { 297a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 298a8eb96d5SAlan Somers char sndbuf[td->pktsize]; 299a8eb96d5SAlan Somers ssize_t ssize; 300a8eb96d5SAlan Somers int i; 301a8eb96d5SAlan Somers 302a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 303a8eb96d5SAlan Somers memset(sndbuf, i, td->pktsize); 304a8eb96d5SAlan Somers ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR); 305a8eb96d5SAlan Somers if (ssize < 0) { 306a8eb96d5SAlan Somers perror("send"); 307a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 308a8eb96d5SAlan Somers } 309a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, ssize, 310a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 311a8eb96d5SAlan Somers td->pktsize, ssize); 312a8eb96d5SAlan Somers } 313a8eb96d5SAlan Somers return (0); 314a8eb96d5SAlan Somers } 315a8eb96d5SAlan Somers 316a8eb96d5SAlan Somers static void* 317a8eb96d5SAlan Somers test_pipe_reader(void* args) 318a8eb96d5SAlan Somers { 319a8eb96d5SAlan Somers test_pipe_thread_data_t* td = args; 320a8eb96d5SAlan Somers char rcvbuf[td->pktsize]; 321a8eb96d5SAlan Somers char comparebuf[td->pktsize]; 322a8eb96d5SAlan Somers ssize_t rsize; 323a8eb96d5SAlan Somers int i, d; 324a8eb96d5SAlan Somers 325a8eb96d5SAlan Somers for(i=0; i < td->numpkts; i++) { 326a8eb96d5SAlan Somers memset(comparebuf, i, td->pktsize); 327a8eb96d5SAlan Somers rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL); 328a8eb96d5SAlan Somers if (rsize < 0) { 329a8eb96d5SAlan Somers perror("recv"); 330a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 331a8eb96d5SAlan Somers } 332a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(td->pktsize, rsize, 333a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", 334a8eb96d5SAlan Somers td->pktsize, rsize); 335a8eb96d5SAlan Somers d = memcmp(comparebuf, rcvbuf, td->pktsize); 336a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, d, 337a8eb96d5SAlan Somers "Received data miscompare on packet %d", i); 338a8eb96d5SAlan Somers } 339a8eb96d5SAlan Somers return (0); 340a8eb96d5SAlan Somers } 341a8eb96d5SAlan Somers 342a8eb96d5SAlan Somers 3435d5b721aSAlan Somers static void 344a8eb96d5SAlan Somers test_pipe(size_t sndbufsize, size_t rcvbufsize) 345a8eb96d5SAlan Somers { 346a8eb96d5SAlan Somers test_pipe_thread_data_t writer_data, reader_data; 347a8eb96d5SAlan Somers pthread_t writer, reader; 348a8eb96d5SAlan Somers int sv[2]; 349a8eb96d5SAlan Somers const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 350a8eb96d5SAlan Somers int numpkts; 351a8eb96d5SAlan Somers 352a8eb96d5SAlan Somers /* setup the socket pair */ 353a8eb96d5SAlan Somers do_socketpair(sv); 354a8eb96d5SAlan Somers /* Setup the buffers */ 355a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 356a8eb96d5SAlan Somers sizeof(sndbufsize))); 357a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 358a8eb96d5SAlan Somers sizeof(rcvbufsize))); 359a8eb96d5SAlan Somers 360a8eb96d5SAlan Somers /* Send a total amount of data comfortably greater than the buffers */ 361a8eb96d5SAlan Somers numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize; 362a8eb96d5SAlan Somers 363a8eb96d5SAlan Somers /* Start the child threads */ 364a8eb96d5SAlan Somers writer_data.pktsize = pktsize; 365a8eb96d5SAlan Somers writer_data.numpkts = numpkts; 366a8eb96d5SAlan Somers writer_data.so = sv[0]; 367a8eb96d5SAlan Somers reader_data.pktsize = pktsize; 368a8eb96d5SAlan Somers reader_data.numpkts = numpkts; 369a8eb96d5SAlan Somers reader_data.so = sv[1]; 370a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer, 371a8eb96d5SAlan Somers (void*)&writer_data)); 3728de34a88SAlan Somers /* 3738de34a88SAlan Somers * Give the writer time to start writing, and hopefully block, before 3748de34a88SAlan Somers * starting the reader. This increases the likelihood of the test case 3758de34a88SAlan Somers * failing due to PR kern/185812 3768de34a88SAlan Somers */ 3778de34a88SAlan Somers usleep(1000); 378a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader, 379a8eb96d5SAlan Somers (void*)&reader_data)); 380a8eb96d5SAlan Somers 381a8eb96d5SAlan Somers /* Join the children */ 382a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(writer, NULL)); 383a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, pthread_join(reader, NULL)); 384e594026dSAlan Somers close(sv[0]); 385e594026dSAlan Somers close(sv[1]); 386a8eb96d5SAlan Somers } 387a8eb96d5SAlan Somers 388a8eb96d5SAlan Somers 389a8eb96d5SAlan Somers /* 390a8eb96d5SAlan Somers * Test Cases 391a8eb96d5SAlan Somers */ 392a8eb96d5SAlan Somers 393a8eb96d5SAlan Somers /* Create a SEQPACKET socket */ 394a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socket); 395a8eb96d5SAlan Somers ATF_TC_BODY(create_socket, tc) 396a8eb96d5SAlan Somers { 397a8eb96d5SAlan Somers int s; 398a8eb96d5SAlan Somers 399a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 4006addc01eSAlan Somers ATF_REQUIRE(s >= 0); 401e594026dSAlan Somers close(s); 402a8eb96d5SAlan Somers } 403a8eb96d5SAlan Somers 404a8eb96d5SAlan Somers /* Create SEQPACKET sockets using socketpair(2) */ 405a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(create_socketpair); 406a8eb96d5SAlan Somers ATF_TC_BODY(create_socketpair, tc) 407a8eb96d5SAlan Somers { 408a8eb96d5SAlan Somers int sv[2]; 409a8eb96d5SAlan Somers int s; 410a8eb96d5SAlan Somers 411a8eb96d5SAlan Somers s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 412a8eb96d5SAlan Somers ATF_CHECK_EQ(0, s); 413a8eb96d5SAlan Somers ATF_CHECK(sv[0] >= 0); 414a8eb96d5SAlan Somers ATF_CHECK(sv[1] >= 0); 415a8eb96d5SAlan Somers ATF_CHECK(sv[0] != sv[1]); 416e594026dSAlan Somers close(sv[0]); 417e594026dSAlan Somers close(sv[1]); 418a8eb96d5SAlan Somers } 419a8eb96d5SAlan Somers 420a8eb96d5SAlan Somers /* Call listen(2) without first calling bind(2). It should fail */ 421a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_unbound); 422a8eb96d5SAlan Somers ATF_TC_BODY(listen_unbound, tc) 423a8eb96d5SAlan Somers { 424a8eb96d5SAlan Somers int s, r; 425a8eb96d5SAlan Somers 426a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 427a8eb96d5SAlan Somers ATF_REQUIRE(s > 0); 428a8eb96d5SAlan Somers r = listen(s, -1); 429a8eb96d5SAlan Somers /* expect listen to fail since we haven't called bind(2) */ 430a8eb96d5SAlan Somers ATF_CHECK(r != 0); 431e594026dSAlan Somers close(s); 432a8eb96d5SAlan Somers } 433a8eb96d5SAlan Somers 434a8eb96d5SAlan Somers /* Bind the socket to a file */ 435a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(bind); 436a8eb96d5SAlan Somers ATF_TC_BODY(bind, tc) 437a8eb96d5SAlan Somers { 438a8eb96d5SAlan Somers struct sockaddr_un sun; 439a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 440a8eb96d5SAlan Somers const char *path = "sock"; 441a8eb96d5SAlan Somers int s, r; 442a8eb96d5SAlan Somers 443a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 444a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 445a8eb96d5SAlan Somers 446a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 447a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 448a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 449a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 450a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 451a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 452e594026dSAlan Somers close(s); 453a8eb96d5SAlan Somers } 454a8eb96d5SAlan Somers 455a8eb96d5SAlan Somers /* listen(2) a socket that is already bound(2) should succeed */ 456a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(listen_bound); 457a8eb96d5SAlan Somers ATF_TC_BODY(listen_bound, tc) 458a8eb96d5SAlan Somers { 459a8eb96d5SAlan Somers struct sockaddr_un sun; 460a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 461a8eb96d5SAlan Somers const char *path = "sock"; 462a8eb96d5SAlan Somers int s, r, l; 463a8eb96d5SAlan Somers 464a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 465a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 466a8eb96d5SAlan Somers 467a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 468a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 469a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 470a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 471a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 472a8eb96d5SAlan Somers l = listen(s, -1); 473a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 474a8eb96d5SAlan Somers ATF_CHECK_EQ(0, l); 475e594026dSAlan Somers close(s); 476a8eb96d5SAlan Somers } 477a8eb96d5SAlan Somers 478a8eb96d5SAlan Somers /* connect(2) can make a connection */ 479a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(connect); 480a8eb96d5SAlan Somers ATF_TC_BODY(connect, tc) 481a8eb96d5SAlan Somers { 482a8eb96d5SAlan Somers struct sockaddr_un sun; 483a8eb96d5SAlan Somers /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 484a8eb96d5SAlan Somers const char *path = "sock"; 485a8eb96d5SAlan Somers int s, r, err, l, s2; 486a8eb96d5SAlan Somers 487a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 488a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 489a8eb96d5SAlan Somers 490a8eb96d5SAlan Somers bzero(&sun, sizeof(sun)); 491a8eb96d5SAlan Somers sun.sun_family = AF_LOCAL; 492a8eb96d5SAlan Somers sun.sun_len = sizeof(sun); 493a8eb96d5SAlan Somers strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 494a8eb96d5SAlan Somers r = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 495a8eb96d5SAlan Somers l = listen(s, -1); 496a8eb96d5SAlan Somers ATF_CHECK_EQ(0, r); 497a8eb96d5SAlan Somers ATF_CHECK_EQ(0, l); 498a8eb96d5SAlan Somers 499a8eb96d5SAlan Somers /* Create the other socket */ 500a8eb96d5SAlan Somers s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 501a8eb96d5SAlan Somers ATF_REQUIRE(s2 >= 0); 502a8eb96d5SAlan Somers err = connect(s2, (struct sockaddr*)&sun, sizeof(sun)); 503a8eb96d5SAlan Somers if (err != 0) { 504a8eb96d5SAlan Somers perror("connect"); 505a8eb96d5SAlan Somers atf_tc_fail("connect(2) failed"); 506a8eb96d5SAlan Somers } 507e594026dSAlan Somers close(s); 508e594026dSAlan Somers close(s2); 509a8eb96d5SAlan Somers } 510a8eb96d5SAlan Somers 511a8eb96d5SAlan Somers /* accept(2) can receive a connection */ 512a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(accept); 513a8eb96d5SAlan Somers ATF_TC_BODY(accept, tc) 514a8eb96d5SAlan Somers { 515a8eb96d5SAlan Somers int sv[2]; 516a8eb96d5SAlan Somers 517a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 518e594026dSAlan Somers close(sv[0]); 519e594026dSAlan Somers close(sv[1]); 520a8eb96d5SAlan Somers } 521a8eb96d5SAlan Somers 522a8eb96d5SAlan Somers 523a8eb96d5SAlan Somers /* Set O_NONBLOCK on the socket */ 524a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(fcntl_nonblock); 525a8eb96d5SAlan Somers ATF_TC_BODY(fcntl_nonblock, tc) 526a8eb96d5SAlan Somers { 527a8eb96d5SAlan Somers int s; 528a8eb96d5SAlan Somers 529a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 530a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 531a8eb96d5SAlan Somers if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) { 532a8eb96d5SAlan Somers perror("fcntl"); 533a8eb96d5SAlan Somers atf_tc_fail("fcntl failed"); 534a8eb96d5SAlan Somers } 535e594026dSAlan Somers close(s); 536a8eb96d5SAlan Somers } 537a8eb96d5SAlan Somers 538a8eb96d5SAlan Somers /* Resize the send and receive buffers */ 539a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_buffers); 540a8eb96d5SAlan Somers ATF_TC_BODY(resize_buffers, tc) 541a8eb96d5SAlan Somers { 542a8eb96d5SAlan Somers int s; 543a8eb96d5SAlan Somers int sndbuf = 12345; 544a8eb96d5SAlan Somers int rcvbuf = 23456; 545a8eb96d5SAlan Somers int xs, xr; 546a8eb96d5SAlan Somers socklen_t sl = sizeof(xs); 547a8eb96d5SAlan Somers 548a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 549a8eb96d5SAlan Somers ATF_REQUIRE(s >= 0); 550a8eb96d5SAlan Somers 551a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 552a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF |\n"); 553a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 554a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 555a8eb96d5SAlan Somers printf("Default | %7d | %7d |\n", xs, xr); 556a8eb96d5SAlan Somers 557a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0){ 558a8eb96d5SAlan Somers perror("setsockopt"); 559a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 560a8eb96d5SAlan Somers } 561a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 562a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 563a8eb96d5SAlan Somers printf("After changing SNDBUF | %7d | %7d |\n", xs, xr); 564a8eb96d5SAlan Somers 565a8eb96d5SAlan Somers if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){ 566a8eb96d5SAlan Somers perror("setsockopt"); 567a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 568a8eb96d5SAlan Somers } 569a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl)); 570a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl)); 571a8eb96d5SAlan Somers printf("After changing RCVBUF | %7d | %7d |\n", xs, xr); 572e594026dSAlan Somers close(s); 573a8eb96d5SAlan Somers } 574a8eb96d5SAlan Somers 575a8eb96d5SAlan Somers /* 576a8eb96d5SAlan Somers * Resize the send and receive buffers of a connected socketpair 577a8eb96d5SAlan Somers * Print some useful debugging info too 578a8eb96d5SAlan Somers */ 579a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(resize_connected_buffers); 580a8eb96d5SAlan Somers ATF_TC_BODY(resize_connected_buffers, tc) 581a8eb96d5SAlan Somers { 582a8eb96d5SAlan Somers int sv[2]; 583a8eb96d5SAlan Somers int sndbuf = 12345; 584a8eb96d5SAlan Somers int rcvbuf = 23456; 585a8eb96d5SAlan Somers int err; 586a8eb96d5SAlan Somers int ls, lr, rs, rr; 587a8eb96d5SAlan Somers socklen_t sl = sizeof(ls); 588a8eb96d5SAlan Somers 589a8eb96d5SAlan Somers /* setup the socket pair */ 590a8eb96d5SAlan Somers do_socketpair(sv); 591a8eb96d5SAlan Somers 592a8eb96d5SAlan Somers printf(" Socket Buffer Sizes\n"); 593a8eb96d5SAlan Somers printf(" | Left Socket | Right Socket |\n"); 594a8eb96d5SAlan Somers printf(" | SNDBUF | RCVBUF | SNDBUF | RCVBUF |\n"); 595a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 596a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 597a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 598a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 599a8eb96d5SAlan Somers printf("Default | %7d | %7d | %7d | %7d |\n", 600a8eb96d5SAlan Somers ls, lr, rs, rr); 601a8eb96d5SAlan Somers 602a8eb96d5SAlan Somers /* Update one side's send buffer */ 603a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)); 604a8eb96d5SAlan Somers if (err != 0){ 605a8eb96d5SAlan Somers perror("setsockopt"); 606a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_SNDBUF) failed"); 607a8eb96d5SAlan Somers } 608a8eb96d5SAlan Somers 609a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 610a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 611a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 612a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 613a8eb96d5SAlan Somers printf("After changing Left's SNDBUF | %7d | %7d | %7d | %7d |\n", 614a8eb96d5SAlan Somers ls, lr, rs, rr); 615a8eb96d5SAlan Somers 616a8eb96d5SAlan Somers /* Update the same side's receive buffer */ 617a8eb96d5SAlan Somers err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); 618a8eb96d5SAlan Somers if (err != 0){ 619a8eb96d5SAlan Somers perror("setsockopt"); 620a8eb96d5SAlan Somers atf_tc_fail("setsockopt(SO_RCVBUF) failed"); 621a8eb96d5SAlan Somers } 622a8eb96d5SAlan Somers 623a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl)); 624a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl)); 625a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl)); 626a8eb96d5SAlan Somers ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl)); 627a8eb96d5SAlan Somers printf("After changing Left's RCVBUF | %7d | %7d | %7d | %7d |\n", 628a8eb96d5SAlan Somers ls, lr, rs, rr); 629e594026dSAlan Somers close(sv[0]); 630e594026dSAlan Somers close(sv[1]); 631a8eb96d5SAlan Somers } 632a8eb96d5SAlan Somers 633a8eb96d5SAlan Somers 634a8eb96d5SAlan Somers /* send(2) and recv(2) a single short record */ 635a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv); 636a8eb96d5SAlan Somers ATF_TC_BODY(send_recv, tc) 637a8eb96d5SAlan Somers { 638a8eb96d5SAlan Somers int sv[2]; 639a8eb96d5SAlan Somers const int bufsize = 64; 640a8eb96d5SAlan Somers const char *data = "data"; 641a8eb96d5SAlan Somers char recv_buf[bufsize]; 6425d5b721aSAlan Somers ssize_t datalen; 643a8eb96d5SAlan Somers ssize_t ssize, rsize; 644a8eb96d5SAlan Somers 645a8eb96d5SAlan Somers /* setup the socket pair */ 646a8eb96d5SAlan Somers do_socketpair(sv); 647a8eb96d5SAlan Somers 648a8eb96d5SAlan Somers /* send and receive a small packet */ 649a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 650a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 651a8eb96d5SAlan Somers if (ssize < 0) { 652a8eb96d5SAlan Somers perror("send"); 653a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 654a8eb96d5SAlan Somers } 655a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 656a8eb96d5SAlan Somers datalen, ssize); 657a8eb96d5SAlan Somers 658a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 659a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 660e594026dSAlan Somers close(sv[0]); 661e594026dSAlan Somers close(sv[1]); 662a8eb96d5SAlan Somers } 663a8eb96d5SAlan Somers 664a8eb96d5SAlan Somers /* sendto(2) and recvfrom(2) a single short record 665a8eb96d5SAlan Somers * According to The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 666a8eb96d5SAlan Somers * Edition, sendto(2) is exactly the same as send(2) on a connection-mode socket 667a8eb96d5SAlan Somers * 668a8eb96d5SAlan Somers * According to the same spec, not all protocols are required to provide the 669a8eb96d5SAlan Somers * source addres in recvfrom(2). 670a8eb96d5SAlan Somers */ 671a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendto_recvfrom); 672a8eb96d5SAlan Somers ATF_TC_BODY(sendto_recvfrom, tc) 673a8eb96d5SAlan Somers { 674a8eb96d5SAlan Somers const char* path; 675a8eb96d5SAlan Somers struct sockaddr_storage from; 676a8eb96d5SAlan Somers int sv[2]; 677a8eb96d5SAlan Somers const int bufsize = 64; 678a8eb96d5SAlan Somers const char *data = "data"; 679a8eb96d5SAlan Somers char recv_buf[bufsize]; 6805d5b721aSAlan Somers ssize_t datalen; 681a8eb96d5SAlan Somers ssize_t ssize, rsize; 682a8eb96d5SAlan Somers socklen_t fromlen; 683a8eb96d5SAlan Somers 684a8eb96d5SAlan Somers /* setup the socket pair */ 685a8eb96d5SAlan Somers path = mk_pair_of_sockets(sv); 686a8eb96d5SAlan Somers 687a8eb96d5SAlan Somers /* send and receive a small packet */ 688a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 689a8eb96d5SAlan Somers ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0); 690a8eb96d5SAlan Somers if (ssize < 0) { 691a8eb96d5SAlan Somers perror("send"); 692a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 693a8eb96d5SAlan Somers } 694a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 695a8eb96d5SAlan Somers datalen, ssize); 696a8eb96d5SAlan Somers 697a8eb96d5SAlan Somers fromlen = sizeof(from); 698a8eb96d5SAlan Somers rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL, 699a8eb96d5SAlan Somers (struct sockaddr*)&from, &fromlen); 700a8eb96d5SAlan Somers if (ssize < 0) { 701a8eb96d5SAlan Somers perror("recvfrom"); 702a8eb96d5SAlan Somers atf_tc_fail("recvfrom returned < 0"); 703a8eb96d5SAlan Somers } 704a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 705a8eb96d5SAlan Somers 706a8eb96d5SAlan Somers /* 707a8eb96d5SAlan Somers * FreeBSD does not currently provide the source address for SEQ_PACKET 708a8eb96d5SAlan Somers * AF_UNIX sockets, and POSIX does not require it, so these two checks 709a8eb96d5SAlan Somers * are disabled. If FreeBSD gains that feature in the future, then 710a8eb96d5SAlan Somers * these checks may be reenabled 711a8eb96d5SAlan Somers */ 712a8eb96d5SAlan Somers /* ATF_CHECK_EQ(PF_LOCAL, from.ss_family); */ 713a8eb96d5SAlan Somers /* ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path); */ 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 { 754a8eb96d5SAlan Somers int s; 755e594026dSAlan Somers const char data[] = "data"; 756a8eb96d5SAlan Somers ssize_t ssize; 757a8eb96d5SAlan Somers 758a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 759e594026dSAlan Somers ATF_REQUIRE(s >= 0); 760a8eb96d5SAlan Somers ATF_CHECK_EQ(0, shutdown(s, SHUT_RDWR)); 761a8eb96d5SAlan Somers /* USE MSG_NOSIGNAL so we don't get SIGPIPE */ 762a8eb96d5SAlan Somers ssize = send(s, data, sizeof(data), MSG_EOR | MSG_NOSIGNAL); 763a8eb96d5SAlan Somers ATF_CHECK_EQ(EPIPE, errno); 764a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 765e594026dSAlan Somers close(s); 766a8eb96d5SAlan Somers } 767a8eb96d5SAlan Somers 768a8eb96d5SAlan Somers /* send(2) should cause SIGPIPE on a shutdown socket */ 769a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe); 770a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send_sigpipe, tc) 771a8eb96d5SAlan Somers { 772a8eb96d5SAlan Somers int s; 773e594026dSAlan Somers const char data[] = "data"; 774a8eb96d5SAlan Somers ssize_t ssize; 775a8eb96d5SAlan Somers 776a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 777e594026dSAlan Somers ATF_REQUIRE(s >= 0); 778a8eb96d5SAlan Somers ATF_CHECK_EQ(0, shutdown(s, SHUT_RDWR)); 779a8eb96d5SAlan Somers ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); 780a8eb96d5SAlan Somers ssize = send(s, data, sizeof(data), MSG_EOR); 781a8eb96d5SAlan Somers ATF_CHECK_EQ(1, got_sigpipe); 782e594026dSAlan Somers close(s); 783a8eb96d5SAlan Somers } 784a8eb96d5SAlan Somers 785a8eb96d5SAlan Somers /* nonblocking send(2) and recv(2) a single short record */ 786a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 787a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_nonblocking, tc) 788a8eb96d5SAlan Somers { 789a8eb96d5SAlan Somers int sv[2]; 790a8eb96d5SAlan Somers const int bufsize = 64; 791a8eb96d5SAlan Somers const char *data = "data"; 792a8eb96d5SAlan Somers char recv_buf[bufsize]; 7935d5b721aSAlan Somers ssize_t datalen; 794a8eb96d5SAlan Somers ssize_t ssize, rsize; 795a8eb96d5SAlan Somers 796a8eb96d5SAlan Somers /* setup the socket pair */ 797a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 798a8eb96d5SAlan Somers 799a8eb96d5SAlan Somers /* Verify that there is nothing to receive */ 800a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 801a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 802a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 803a8eb96d5SAlan Somers 804a8eb96d5SAlan Somers /* send and receive a small packet */ 805a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 806a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 807a8eb96d5SAlan Somers if (ssize < 0) { 808a8eb96d5SAlan Somers perror("send"); 809a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 810a8eb96d5SAlan Somers } 811a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 812a8eb96d5SAlan Somers datalen, ssize); 813a8eb96d5SAlan Somers 814a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 815a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 816e594026dSAlan Somers close(sv[0]); 817e594026dSAlan Somers close(sv[1]); 818a8eb96d5SAlan Somers } 819a8eb96d5SAlan Somers 820a8eb96d5SAlan Somers /* 821a8eb96d5SAlan Somers * We should get EMSGSIZE if we try to send a message larger than the socket 822a8eb96d5SAlan Somers * buffer, with blocking sockets 823a8eb96d5SAlan Somers */ 824a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(emsgsize); 825a8eb96d5SAlan Somers ATF_TC_BODY(emsgsize, tc) 826a8eb96d5SAlan Somers { 827a8eb96d5SAlan Somers int sv[2]; 828a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 829a8eb96d5SAlan Somers const size_t rcvbufsize = 8192; 830a8eb96d5SAlan Somers const size_t pktsize = (sndbufsize + rcvbufsize) * 2; 831a8eb96d5SAlan Somers char sndbuf[pktsize]; 8325d5b721aSAlan Somers ssize_t ssize; 833a8eb96d5SAlan Somers 834a8eb96d5SAlan Somers /* setup the socket pair */ 835a8eb96d5SAlan Somers do_socketpair(sv); 836a8eb96d5SAlan Somers /* Setup the buffers */ 837a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 838a8eb96d5SAlan Somers sizeof(sndbufsize))); 839a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 840a8eb96d5SAlan Somers sizeof(rcvbufsize))); 841a8eb96d5SAlan Somers 842a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 843a8eb96d5SAlan Somers ATF_CHECK_EQ(EMSGSIZE, errno); 844a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 845e594026dSAlan Somers close(sv[0]); 846e594026dSAlan Somers close(sv[1]); 847a8eb96d5SAlan Somers } 848a8eb96d5SAlan Somers 849a8eb96d5SAlan Somers /* 850a8eb96d5SAlan Somers * We should get EMSGSIZE if we try to send a message larger than the socket 851a8eb96d5SAlan Somers * buffer, with nonblocking sockets 852a8eb96d5SAlan Somers */ 853a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(emsgsize_nonblocking); 854a8eb96d5SAlan Somers ATF_TC_BODY(emsgsize_nonblocking, tc) 855a8eb96d5SAlan Somers { 856a8eb96d5SAlan Somers int sv[2]; 857a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 858a8eb96d5SAlan Somers const size_t rcvbufsize = 8192; 859a8eb96d5SAlan Somers const size_t pktsize = (sndbufsize + rcvbufsize) * 2; 860a8eb96d5SAlan Somers char sndbuf[pktsize]; 8615d5b721aSAlan Somers ssize_t ssize; 862a8eb96d5SAlan Somers 863a8eb96d5SAlan Somers /* setup the socket pair */ 864a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 865a8eb96d5SAlan Somers /* Setup the buffers */ 866a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 867a8eb96d5SAlan Somers sizeof(sndbufsize))); 868a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 869a8eb96d5SAlan Somers sizeof(rcvbufsize))); 870a8eb96d5SAlan Somers 871a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 872a8eb96d5SAlan Somers ATF_CHECK_EQ(EMSGSIZE, errno); 873a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 874e594026dSAlan Somers close(sv[0]); 875e594026dSAlan Somers close(sv[1]); 876a8eb96d5SAlan Somers } 877a8eb96d5SAlan Somers 878a8eb96d5SAlan Somers 879a8eb96d5SAlan Somers /* 880a8eb96d5SAlan Somers * We should get EAGAIN if we try to send a message larger than the socket 881a8eb96d5SAlan Somers * buffer, with nonblocking sockets. Test with several different sockbuf sizes 882a8eb96d5SAlan Somers */ 883a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_8k); 884a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_8k, tc) 885a8eb96d5SAlan Somers { 886a8eb96d5SAlan Somers test_eagain(8192, 8192); 887a8eb96d5SAlan Somers } 888a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_128k); 889a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_128k, tc) 890a8eb96d5SAlan Somers { 891a8eb96d5SAlan Somers test_eagain(8192, 131072); 892a8eb96d5SAlan Somers } 893a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_8k); 894a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_8k, tc) 895a8eb96d5SAlan Somers { 896a8eb96d5SAlan Somers test_eagain(131072, 8192); 897a8eb96d5SAlan Somers } 898a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_128k); 899a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_128k, tc) 900a8eb96d5SAlan Somers { 901a8eb96d5SAlan Somers test_eagain(131072, 131072); 902a8eb96d5SAlan Somers } 903a8eb96d5SAlan Somers 904a8eb96d5SAlan Somers 905a8eb96d5SAlan Somers /* 906a8eb96d5SAlan Somers * nonblocking send(2) and recv(2) of several records, which should collectively 907a8eb96d5SAlan Somers * fill up the send buffer but not the receive buffer 908a8eb96d5SAlan Somers */ 909a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(rcvbuf_oversized); 910a8eb96d5SAlan Somers ATF_TC_BODY(rcvbuf_oversized, tc) 911a8eb96d5SAlan Somers { 9125d5b721aSAlan Somers int i; 913a8eb96d5SAlan Somers int sv[2]; 9143be7751dSJulio Merino const ssize_t pktsize = 1024; 915a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 916a8eb96d5SAlan Somers const size_t rcvbufsize = 131072; 9175d5b721aSAlan Somers const size_t geometric_mean_bufsize = 32768; 9185d5b721aSAlan Somers const int numpkts = geometric_mean_bufsize / pktsize; 919a8eb96d5SAlan Somers char sndbuf[pktsize]; 920a8eb96d5SAlan Somers char recv_buf[pktsize]; 921a8eb96d5SAlan Somers ssize_t ssize, rsize; 922a8eb96d5SAlan Somers 923a8eb96d5SAlan Somers /* setup the socket pair */ 924a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 9255d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 9265d5b721aSAlan Somers sizeof(sndbufsize))); 9275d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 9285d5b721aSAlan Somers sizeof(rcvbufsize))); 929a8eb96d5SAlan Somers 930a8eb96d5SAlan Somers /* 931a8eb96d5SAlan Somers * Send and receive packets that are collectively greater than the send 932a8eb96d5SAlan Somers * buffer, but less than the receive buffer 933a8eb96d5SAlan Somers */ 9345d5b721aSAlan Somers for (i=0; i < numpkts; i++) { 935a8eb96d5SAlan Somers /* Fill the buffer */ 936a8eb96d5SAlan Somers memset(sndbuf, i, pktsize); 937a8eb96d5SAlan Somers 938a8eb96d5SAlan Somers /* send the packet */ 939a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 940a8eb96d5SAlan Somers if (ssize < 0) { 941a8eb96d5SAlan Somers perror("send"); 942a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 943a8eb96d5SAlan Somers } 944a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 945a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, ssize); 946a8eb96d5SAlan Somers 947a8eb96d5SAlan Somers /* Receive it */ 948a8eb96d5SAlan Somers 949a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 950a8eb96d5SAlan Somers if (rsize < 0) { 951a8eb96d5SAlan Somers perror("recv"); 952a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 953a8eb96d5SAlan Somers } 954a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 955a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, rsize); 956a8eb96d5SAlan Somers 957a8eb96d5SAlan Somers /* Verify the contents */ 958a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), 959a8eb96d5SAlan Somers "Received data miscompare"); 960a8eb96d5SAlan Somers } 961a8eb96d5SAlan Somers 962a8eb96d5SAlan Somers /* Trying to receive again should return EAGAIN */ 963a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 964a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 965a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 966e594026dSAlan Somers close(sv[0]); 967e594026dSAlan Somers close(sv[1]); 968a8eb96d5SAlan Somers } 969a8eb96d5SAlan Somers 970a8eb96d5SAlan Somers /* 971a8eb96d5SAlan Somers * Simulate the behavior of a blocking pipe. The sender will send until his 972a8eb96d5SAlan Somers * buffer fills up, then we'll simulate a scheduler switch that will allow the 973a8eb96d5SAlan Somers * receiver to read until his buffer empties. Repeat the process until the 974a8eb96d5SAlan Somers * transfer is complete. 975a8eb96d5SAlan Somers * Repeat the test with multiple send and receive buffer sizes 976a8eb96d5SAlan Somers */ 977a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k); 978a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_8k, tc) 979a8eb96d5SAlan Somers { 980a8eb96d5SAlan Somers test_pipe_simulator(8192, 8192); 981a8eb96d5SAlan Somers } 982a8eb96d5SAlan Somers 983a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k); 984a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_128k, tc) 985a8eb96d5SAlan Somers { 986a8eb96d5SAlan Somers test_pipe_simulator(8192, 131072); 987a8eb96d5SAlan Somers } 988a8eb96d5SAlan Somers 989a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k); 990a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_8k, tc) 991a8eb96d5SAlan Somers { 992a8eb96d5SAlan Somers test_pipe_simulator(131072, 8192); 993a8eb96d5SAlan Somers } 994a8eb96d5SAlan Somers 995a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k); 996a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_128k, tc) 997a8eb96d5SAlan Somers { 998a8eb96d5SAlan Somers test_pipe_simulator(131072, 131072); 999a8eb96d5SAlan Somers } 1000a8eb96d5SAlan Somers 1001a8eb96d5SAlan Somers /* 1002a8eb96d5SAlan Somers * Test blocking I/O by passing data between two threads. The total amount of 1003a8eb96d5SAlan Somers * data will be >> buffer size to force blocking. Repeat the test with multiple 1004a8eb96d5SAlan Somers * send and receive buffer sizes 1005a8eb96d5SAlan Somers */ 1006a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_8k); 1007a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_8k, tc) 1008a8eb96d5SAlan Somers { 1009a8eb96d5SAlan Somers test_pipe(8192, 8192); 1010a8eb96d5SAlan Somers } 1011a8eb96d5SAlan Somers 1012a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_128k); 1013a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_128k, tc) 1014a8eb96d5SAlan Somers { 1015a8eb96d5SAlan Somers test_pipe(8192, 131072); 1016a8eb96d5SAlan Somers } 1017a8eb96d5SAlan Somers 1018a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_8k); 1019a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_8k, tc) 1020a8eb96d5SAlan Somers { 1021a8eb96d5SAlan Somers test_pipe(131072, 8192); 1022a8eb96d5SAlan Somers } 1023a8eb96d5SAlan Somers 1024a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_128k); 1025a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_128k, tc) 1026a8eb96d5SAlan Somers { 1027a8eb96d5SAlan Somers test_pipe(131072, 131072); 1028a8eb96d5SAlan Somers } 1029a8eb96d5SAlan Somers 1030a8eb96d5SAlan Somers 1031a8eb96d5SAlan Somers /* 1032a8eb96d5SAlan Somers * Test single-packet I/O with and without blocking, with symmetric buffers of 1033a8eb96d5SAlan Somers * various sizes 1034a8eb96d5SAlan Somers */ 1035a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k); 1036a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k, tc) 1037a8eb96d5SAlan Somers { 1038a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, true); 1039a8eb96d5SAlan Somers } 1040a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k); 1041a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k, tc) 1042a8eb96d5SAlan Somers { 1043a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, true); 1044a8eb96d5SAlan Somers } 1045a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k); 1046a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k, tc) 1047a8eb96d5SAlan Somers { 1048a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, true); 1049a8eb96d5SAlan Somers } 1050a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k); 1051a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k, tc) 1052a8eb96d5SAlan Somers { 1053a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, true); 1054a8eb96d5SAlan Somers } 1055a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k); 1056a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k, tc) 1057a8eb96d5SAlan Somers { 1058a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, true); 1059a8eb96d5SAlan Somers } 1060a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking); 1061a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k_nonblocking, tc) 1062a8eb96d5SAlan Somers { 1063a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, false); 1064a8eb96d5SAlan Somers } 1065a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking); 1066a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k_nonblocking, tc) 1067a8eb96d5SAlan Somers { 1068a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, false); 1069a8eb96d5SAlan Somers } 1070a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking); 1071a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k_nonblocking, tc) 1072a8eb96d5SAlan Somers { 1073a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, false); 1074a8eb96d5SAlan Somers } 1075a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking); 1076a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k_nonblocking, tc) 1077a8eb96d5SAlan Somers { 1078a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, false); 1079a8eb96d5SAlan Somers } 1080a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking); 1081a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k_nonblocking, tc) 1082a8eb96d5SAlan Somers { 1083a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, false); 1084a8eb96d5SAlan Somers } 1085a8eb96d5SAlan Somers 1086a8eb96d5SAlan Somers 1087a8eb96d5SAlan Somers /* 1088a8eb96d5SAlan Somers * Main. 1089a8eb96d5SAlan Somers */ 1090a8eb96d5SAlan Somers 1091a8eb96d5SAlan Somers ATF_TP_ADD_TCS(tp) 1092a8eb96d5SAlan Somers { 1093a8eb96d5SAlan Somers /* Basic creation and connection tests */ 1094a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socket); 1095a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socketpair); 1096a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_unbound); 1097a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, bind); 1098a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_bound); 1099a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, connect); 1100a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, accept); 1101a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, fcntl_nonblock); 1102a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_buffers); 1103a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_connected_buffers); 1104a8eb96d5SAlan Somers 1105a8eb96d5SAlan Somers /* Unthreaded I/O tests */ 1106a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv); 1107a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_nonblocking); 1108a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_with_connect); 1109a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendto_recvfrom); 1110a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send); 1111a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send_sigpipe); 1112a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, emsgsize); 1113a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, emsgsize_nonblocking); 1114a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_8k); 1115a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_128k); 1116a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_8k); 1117a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_128k); 1118a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k); 1119a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k); 1120a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k); 1121a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k); 1122a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k); 1123a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking); 1124a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking); 1125a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking); 1126a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking); 1127a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking); 1128a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, rcvbuf_oversized); 1129a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k); 1130a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k); 1131a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k); 1132a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k); 1133a8eb96d5SAlan Somers 1134a8eb96d5SAlan Somers /* Threaded I/O tests with blocking sockets */ 1135a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_8k); 1136a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_128k); 1137a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_8k); 1138a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_128k); 1139a8eb96d5SAlan Somers 1140a8eb96d5SAlan Somers return atf_no_error(); 1141a8eb96d5SAlan Somers } 1142