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 { 674983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 675a8eb96d5SAlan Somers const char* path; 676983a2d91SEnji Cooper #endif 677a8eb96d5SAlan Somers struct sockaddr_storage from; 678a8eb96d5SAlan Somers int sv[2]; 679a8eb96d5SAlan Somers const int bufsize = 64; 680a8eb96d5SAlan Somers const char *data = "data"; 681a8eb96d5SAlan Somers char recv_buf[bufsize]; 6825d5b721aSAlan Somers ssize_t datalen; 683a8eb96d5SAlan Somers ssize_t ssize, rsize; 684a8eb96d5SAlan Somers socklen_t fromlen; 685a8eb96d5SAlan Somers 686a8eb96d5SAlan Somers /* setup the socket pair */ 687983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 688983a2d91SEnji Cooper path = 689983a2d91SEnji Cooper #endif 690983a2d91SEnji Cooper mk_pair_of_sockets(sv); 691a8eb96d5SAlan Somers 692a8eb96d5SAlan Somers /* send and receive a small packet */ 693a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 694a8eb96d5SAlan Somers ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0); 695a8eb96d5SAlan Somers if (ssize < 0) { 696a8eb96d5SAlan Somers perror("send"); 697a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 698a8eb96d5SAlan Somers } 699a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 700a8eb96d5SAlan Somers datalen, ssize); 701a8eb96d5SAlan Somers 702a8eb96d5SAlan Somers fromlen = sizeof(from); 703a8eb96d5SAlan Somers rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL, 704a8eb96d5SAlan Somers (struct sockaddr*)&from, &fromlen); 705a8eb96d5SAlan Somers if (ssize < 0) { 706a8eb96d5SAlan Somers perror("recvfrom"); 707a8eb96d5SAlan Somers atf_tc_fail("recvfrom returned < 0"); 708a8eb96d5SAlan Somers } 709a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 710a8eb96d5SAlan Somers 711983a2d91SEnji Cooper #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS 712a8eb96d5SAlan Somers /* 713a8eb96d5SAlan Somers * FreeBSD does not currently provide the source address for SEQ_PACKET 714a8eb96d5SAlan Somers * AF_UNIX sockets, and POSIX does not require it, so these two checks 715a8eb96d5SAlan Somers * are disabled. If FreeBSD gains that feature in the future, then 716a8eb96d5SAlan Somers * these checks may be reenabled 717a8eb96d5SAlan Somers */ 718983a2d91SEnji Cooper ATF_CHECK_EQ(PF_LOCAL, from.ss_family); 719983a2d91SEnji Cooper ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path); 720983a2d91SEnji Cooper #endif 721e594026dSAlan Somers close(sv[0]); 722e594026dSAlan Somers close(sv[1]); 723a8eb96d5SAlan Somers } 724a8eb96d5SAlan Somers 725a8eb96d5SAlan Somers /* 726a8eb96d5SAlan Somers * send(2) and recv(2) a single short record with sockets created the 727a8eb96d5SAlan Somers * traditional way, involving bind, listen, connect, and accept 728a8eb96d5SAlan Somers */ 729a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_with_connect); 730a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_with_connect, tc) 731a8eb96d5SAlan Somers { 732a8eb96d5SAlan Somers int sv[2]; 733a8eb96d5SAlan Somers const int bufsize = 64; 734a8eb96d5SAlan Somers const char *data = "data"; 735a8eb96d5SAlan Somers char recv_buf[bufsize]; 7365d5b721aSAlan Somers ssize_t datalen; 737a8eb96d5SAlan Somers ssize_t ssize, rsize; 738a8eb96d5SAlan Somers 739a8eb96d5SAlan Somers mk_pair_of_sockets(sv); 740a8eb96d5SAlan Somers 741a8eb96d5SAlan Somers /* send and receive a small packet */ 742a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 743a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 744a8eb96d5SAlan Somers if (ssize < 0) { 745a8eb96d5SAlan Somers perror("send"); 746a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 747a8eb96d5SAlan Somers } 748a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 749a8eb96d5SAlan Somers datalen, ssize); 750a8eb96d5SAlan Somers 751a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 752a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 753e594026dSAlan Somers close(sv[0]); 754e594026dSAlan Somers close(sv[1]); 755a8eb96d5SAlan Somers } 756a8eb96d5SAlan Somers 757a8eb96d5SAlan Somers /* send(2) should fail on a shutdown socket */ 758a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send); 759a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send, tc) 760a8eb96d5SAlan Somers { 7614446a47aSSergey Kandaurov struct sockaddr_un sun; 7624446a47aSSergey Kandaurov /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 7634446a47aSSergey Kandaurov const char *path = "sock"; 7644446a47aSSergey Kandaurov const char *data = "data"; 765a8eb96d5SAlan Somers ssize_t ssize; 7664446a47aSSergey Kandaurov int s, err, s2; 767a8eb96d5SAlan Somers 768a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 769e594026dSAlan Somers ATF_REQUIRE(s >= 0); 7704446a47aSSergey Kandaurov 7714446a47aSSergey Kandaurov bzero(&sun, sizeof(sun)); 7724446a47aSSergey Kandaurov sun.sun_family = AF_LOCAL; 7734446a47aSSergey Kandaurov sun.sun_len = sizeof(sun); 7744446a47aSSergey Kandaurov strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 7754446a47aSSergey Kandaurov err = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 7764446a47aSSergey Kandaurov err = listen(s, -1); 7774446a47aSSergey Kandaurov ATF_CHECK_EQ(0, err); 7784446a47aSSergey Kandaurov 7794446a47aSSergey Kandaurov /* Create the other socket */ 7804446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 7814446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 7824446a47aSSergey Kandaurov err = connect(s2, (struct sockaddr*)&sun, sizeof(sun)); 7834446a47aSSergey Kandaurov if (err != 0) { 7844446a47aSSergey Kandaurov perror("connect"); 7854446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 7864446a47aSSergey Kandaurov } 7874446a47aSSergey Kandaurov 7884446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 789a8eb96d5SAlan Somers /* USE MSG_NOSIGNAL so we don't get SIGPIPE */ 7904446a47aSSergey Kandaurov ssize = send(s2, data, sizeof(data), MSG_EOR | MSG_NOSIGNAL); 791a8eb96d5SAlan Somers ATF_CHECK_EQ(EPIPE, errno); 792a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 793e594026dSAlan Somers close(s); 7944446a47aSSergey Kandaurov close(s2); 795a8eb96d5SAlan Somers } 796a8eb96d5SAlan Somers 797a8eb96d5SAlan Somers /* send(2) should cause SIGPIPE on a shutdown socket */ 798a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe); 799a8eb96d5SAlan Somers ATF_TC_BODY(shutdown_send_sigpipe, tc) 800a8eb96d5SAlan Somers { 8014446a47aSSergey Kandaurov struct sockaddr_un sun; 8024446a47aSSergey Kandaurov /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 8034446a47aSSergey Kandaurov const char *path = "sock"; 8044446a47aSSergey Kandaurov const char *data = "data"; 8054446a47aSSergey Kandaurov int s, err, s2; 806a8eb96d5SAlan Somers 807a8eb96d5SAlan Somers s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 808e594026dSAlan Somers ATF_REQUIRE(s >= 0); 8094446a47aSSergey Kandaurov 8104446a47aSSergey Kandaurov bzero(&sun, sizeof(sun)); 8114446a47aSSergey Kandaurov sun.sun_family = AF_LOCAL; 8124446a47aSSergey Kandaurov sun.sun_len = sizeof(sun); 8134446a47aSSergey Kandaurov strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); 8144446a47aSSergey Kandaurov err = bind(s, (struct sockaddr *)&sun, sizeof(sun)); 8154446a47aSSergey Kandaurov err = listen(s, -1); 8164446a47aSSergey Kandaurov ATF_CHECK_EQ(0, err); 8174446a47aSSergey Kandaurov 8184446a47aSSergey Kandaurov /* Create the other socket */ 8194446a47aSSergey Kandaurov s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0); 8204446a47aSSergey Kandaurov ATF_REQUIRE(s2 >= 0); 8214446a47aSSergey Kandaurov err = connect(s2, (struct sockaddr*)&sun, sizeof(sun)); 8224446a47aSSergey Kandaurov if (err != 0) { 8234446a47aSSergey Kandaurov perror("connect"); 8244446a47aSSergey Kandaurov atf_tc_fail("connect(2) failed"); 8254446a47aSSergey Kandaurov } 8264446a47aSSergey Kandaurov 8274446a47aSSergey Kandaurov ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR)); 828a8eb96d5SAlan Somers ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler)); 829983a2d91SEnji Cooper (void)send(s2, data, sizeof(data), MSG_EOR); 830a8eb96d5SAlan Somers ATF_CHECK_EQ(1, got_sigpipe); 831e594026dSAlan Somers close(s); 8324446a47aSSergey Kandaurov close(s2); 833a8eb96d5SAlan Somers } 834a8eb96d5SAlan Somers 835a8eb96d5SAlan Somers /* nonblocking send(2) and recv(2) a single short record */ 836a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 837a8eb96d5SAlan Somers ATF_TC_BODY(send_recv_nonblocking, tc) 838a8eb96d5SAlan Somers { 839a8eb96d5SAlan Somers int sv[2]; 840a8eb96d5SAlan Somers const int bufsize = 64; 841a8eb96d5SAlan Somers const char *data = "data"; 842a8eb96d5SAlan Somers char recv_buf[bufsize]; 8435d5b721aSAlan Somers ssize_t datalen; 844a8eb96d5SAlan Somers ssize_t ssize, rsize; 845a8eb96d5SAlan Somers 846a8eb96d5SAlan Somers /* setup the socket pair */ 847a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 848a8eb96d5SAlan Somers 849a8eb96d5SAlan Somers /* Verify that there is nothing to receive */ 850a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 851a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 852a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 853a8eb96d5SAlan Somers 854a8eb96d5SAlan Somers /* send and receive a small packet */ 855a8eb96d5SAlan Somers datalen = strlen(data) + 1; /* +1 for the null */ 856a8eb96d5SAlan Somers ssize = send(sv[0], data, datalen, MSG_EOR); 857a8eb96d5SAlan Somers if (ssize < 0) { 858a8eb96d5SAlan Somers perror("send"); 859a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 860a8eb96d5SAlan Somers } 861a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 862a8eb96d5SAlan Somers datalen, ssize); 863a8eb96d5SAlan Somers 864a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 865a8eb96d5SAlan Somers ATF_CHECK_EQ(datalen, rsize); 866e594026dSAlan Somers close(sv[0]); 867e594026dSAlan Somers close(sv[1]); 868a8eb96d5SAlan Somers } 869a8eb96d5SAlan Somers 870a8eb96d5SAlan Somers /* 871a8eb96d5SAlan Somers * We should get EMSGSIZE if we try to send a message larger than the socket 872a8eb96d5SAlan Somers * buffer, with blocking sockets 873a8eb96d5SAlan Somers */ 874a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(emsgsize); 875a8eb96d5SAlan Somers ATF_TC_BODY(emsgsize, tc) 876a8eb96d5SAlan Somers { 877a8eb96d5SAlan Somers int sv[2]; 878a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 879a8eb96d5SAlan Somers const size_t rcvbufsize = 8192; 880a8eb96d5SAlan Somers const size_t pktsize = (sndbufsize + rcvbufsize) * 2; 881a8eb96d5SAlan Somers char sndbuf[pktsize]; 8825d5b721aSAlan Somers ssize_t ssize; 883a8eb96d5SAlan Somers 884a8eb96d5SAlan Somers /* setup the socket pair */ 885a8eb96d5SAlan Somers do_socketpair(sv); 886a8eb96d5SAlan Somers /* Setup the buffers */ 887a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 888a8eb96d5SAlan Somers sizeof(sndbufsize))); 889a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 890a8eb96d5SAlan Somers sizeof(rcvbufsize))); 891a8eb96d5SAlan Somers 892a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 893a8eb96d5SAlan Somers ATF_CHECK_EQ(EMSGSIZE, errno); 894a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 895e594026dSAlan Somers close(sv[0]); 896e594026dSAlan Somers close(sv[1]); 897a8eb96d5SAlan Somers } 898a8eb96d5SAlan Somers 899a8eb96d5SAlan Somers /* 900a8eb96d5SAlan Somers * We should get EMSGSIZE if we try to send a message larger than the socket 901a8eb96d5SAlan Somers * buffer, with nonblocking sockets 902a8eb96d5SAlan Somers */ 903a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(emsgsize_nonblocking); 904a8eb96d5SAlan Somers ATF_TC_BODY(emsgsize_nonblocking, tc) 905a8eb96d5SAlan Somers { 906a8eb96d5SAlan Somers int sv[2]; 907a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 908a8eb96d5SAlan Somers const size_t rcvbufsize = 8192; 909a8eb96d5SAlan Somers const size_t pktsize = (sndbufsize + rcvbufsize) * 2; 910a8eb96d5SAlan Somers char sndbuf[pktsize]; 9115d5b721aSAlan Somers ssize_t ssize; 912a8eb96d5SAlan Somers 913a8eb96d5SAlan Somers /* setup the socket pair */ 914a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 915a8eb96d5SAlan Somers /* Setup the buffers */ 916a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 917a8eb96d5SAlan Somers sizeof(sndbufsize))); 918a8eb96d5SAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 919a8eb96d5SAlan Somers sizeof(rcvbufsize))); 920a8eb96d5SAlan Somers 921a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 922a8eb96d5SAlan Somers ATF_CHECK_EQ(EMSGSIZE, errno); 923a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, ssize); 924e594026dSAlan Somers close(sv[0]); 925e594026dSAlan Somers close(sv[1]); 926a8eb96d5SAlan Somers } 927a8eb96d5SAlan Somers 928a8eb96d5SAlan Somers 929a8eb96d5SAlan Somers /* 930a8eb96d5SAlan Somers * We should get EAGAIN if we try to send a message larger than the socket 931a8eb96d5SAlan Somers * buffer, with nonblocking sockets. Test with several different sockbuf sizes 932a8eb96d5SAlan Somers */ 933a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_8k); 934a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_8k, tc) 935a8eb96d5SAlan Somers { 936a8eb96d5SAlan Somers test_eagain(8192, 8192); 937a8eb96d5SAlan Somers } 938a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_8k_128k); 939a8eb96d5SAlan Somers ATF_TC_BODY(eagain_8k_128k, tc) 940a8eb96d5SAlan Somers { 941a8eb96d5SAlan Somers test_eagain(8192, 131072); 942a8eb96d5SAlan Somers } 943a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_8k); 944a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_8k, tc) 945a8eb96d5SAlan Somers { 946a8eb96d5SAlan Somers test_eagain(131072, 8192); 947a8eb96d5SAlan Somers } 948a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(eagain_128k_128k); 949a8eb96d5SAlan Somers ATF_TC_BODY(eagain_128k_128k, tc) 950a8eb96d5SAlan Somers { 951a8eb96d5SAlan Somers test_eagain(131072, 131072); 952a8eb96d5SAlan Somers } 953a8eb96d5SAlan Somers 954a8eb96d5SAlan Somers 955a8eb96d5SAlan Somers /* 956a8eb96d5SAlan Somers * nonblocking send(2) and recv(2) of several records, which should collectively 957a8eb96d5SAlan Somers * fill up the send buffer but not the receive buffer 958a8eb96d5SAlan Somers */ 959a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(rcvbuf_oversized); 960a8eb96d5SAlan Somers ATF_TC_BODY(rcvbuf_oversized, tc) 961a8eb96d5SAlan Somers { 9625d5b721aSAlan Somers int i; 963a8eb96d5SAlan Somers int sv[2]; 9643be7751dSJulio Merino const ssize_t pktsize = 1024; 965a8eb96d5SAlan Somers const size_t sndbufsize = 8192; 966a8eb96d5SAlan Somers const size_t rcvbufsize = 131072; 9675d5b721aSAlan Somers const size_t geometric_mean_bufsize = 32768; 9685d5b721aSAlan Somers const int numpkts = geometric_mean_bufsize / pktsize; 969a8eb96d5SAlan Somers char sndbuf[pktsize]; 970a8eb96d5SAlan Somers char recv_buf[pktsize]; 971a8eb96d5SAlan Somers ssize_t ssize, rsize; 972a8eb96d5SAlan Somers 973a8eb96d5SAlan Somers /* setup the socket pair */ 974a8eb96d5SAlan Somers do_socketpair_nonblocking(sv); 9755d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 9765d5b721aSAlan Somers sizeof(sndbufsize))); 9775d5b721aSAlan Somers ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 9785d5b721aSAlan Somers sizeof(rcvbufsize))); 979a8eb96d5SAlan Somers 980a8eb96d5SAlan Somers /* 981a8eb96d5SAlan Somers * Send and receive packets that are collectively greater than the send 982a8eb96d5SAlan Somers * buffer, but less than the receive buffer 983a8eb96d5SAlan Somers */ 9845d5b721aSAlan Somers for (i=0; i < numpkts; i++) { 985a8eb96d5SAlan Somers /* Fill the buffer */ 986a8eb96d5SAlan Somers memset(sndbuf, i, pktsize); 987a8eb96d5SAlan Somers 988a8eb96d5SAlan Somers /* send the packet */ 989a8eb96d5SAlan Somers ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 990a8eb96d5SAlan Somers if (ssize < 0) { 991a8eb96d5SAlan Somers perror("send"); 992a8eb96d5SAlan Somers atf_tc_fail("send returned < 0"); 993a8eb96d5SAlan Somers } 994a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, ssize, 995a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, ssize); 996a8eb96d5SAlan Somers 997a8eb96d5SAlan Somers /* Receive it */ 998a8eb96d5SAlan Somers 999a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 1000a8eb96d5SAlan Somers if (rsize < 0) { 1001a8eb96d5SAlan Somers perror("recv"); 1002a8eb96d5SAlan Somers atf_tc_fail("recv returned < 0"); 1003a8eb96d5SAlan Somers } 1004a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(pktsize, rsize, 1005a8eb96d5SAlan Somers "expected %zd=send(...) but got %zd", pktsize, rsize); 1006a8eb96d5SAlan Somers 1007a8eb96d5SAlan Somers /* Verify the contents */ 1008a8eb96d5SAlan Somers ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), 1009a8eb96d5SAlan Somers "Received data miscompare"); 1010a8eb96d5SAlan Somers } 1011a8eb96d5SAlan Somers 1012a8eb96d5SAlan Somers /* Trying to receive again should return EAGAIN */ 1013a8eb96d5SAlan Somers rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 1014a8eb96d5SAlan Somers ATF_CHECK_EQ(EAGAIN, errno); 1015a8eb96d5SAlan Somers ATF_CHECK_EQ(-1, rsize); 1016e594026dSAlan Somers close(sv[0]); 1017e594026dSAlan Somers close(sv[1]); 1018a8eb96d5SAlan Somers } 1019a8eb96d5SAlan Somers 1020a8eb96d5SAlan Somers /* 1021a8eb96d5SAlan Somers * Simulate the behavior of a blocking pipe. The sender will send until his 1022a8eb96d5SAlan Somers * buffer fills up, then we'll simulate a scheduler switch that will allow the 1023a8eb96d5SAlan Somers * receiver to read until his buffer empties. Repeat the process until the 1024a8eb96d5SAlan Somers * transfer is complete. 1025a8eb96d5SAlan Somers * Repeat the test with multiple send and receive buffer sizes 1026a8eb96d5SAlan Somers */ 1027a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k); 1028a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_8k, tc) 1029a8eb96d5SAlan Somers { 1030a8eb96d5SAlan Somers test_pipe_simulator(8192, 8192); 1031a8eb96d5SAlan Somers } 1032a8eb96d5SAlan Somers 1033a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k); 1034a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_8k_128k, tc) 1035a8eb96d5SAlan Somers { 1036a8eb96d5SAlan Somers test_pipe_simulator(8192, 131072); 1037a8eb96d5SAlan Somers } 1038a8eb96d5SAlan Somers 1039a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k); 1040a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_8k, tc) 1041a8eb96d5SAlan Somers { 1042a8eb96d5SAlan Somers test_pipe_simulator(131072, 8192); 1043a8eb96d5SAlan Somers } 1044a8eb96d5SAlan Somers 1045a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k); 1046a8eb96d5SAlan Somers ATF_TC_BODY(pipe_simulator_128k_128k, tc) 1047a8eb96d5SAlan Somers { 1048a8eb96d5SAlan Somers test_pipe_simulator(131072, 131072); 1049a8eb96d5SAlan Somers } 1050a8eb96d5SAlan Somers 1051a8eb96d5SAlan Somers /* 1052a8eb96d5SAlan Somers * Test blocking I/O by passing data between two threads. The total amount of 1053a8eb96d5SAlan Somers * data will be >> buffer size to force blocking. Repeat the test with multiple 1054a8eb96d5SAlan Somers * send and receive buffer sizes 1055a8eb96d5SAlan Somers */ 1056a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_8k); 1057a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_8k, tc) 1058a8eb96d5SAlan Somers { 1059a8eb96d5SAlan Somers test_pipe(8192, 8192); 1060a8eb96d5SAlan Somers } 1061a8eb96d5SAlan Somers 1062a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_8k_128k); 1063a8eb96d5SAlan Somers ATF_TC_BODY(pipe_8k_128k, tc) 1064a8eb96d5SAlan Somers { 1065a8eb96d5SAlan Somers test_pipe(8192, 131072); 1066a8eb96d5SAlan Somers } 1067a8eb96d5SAlan Somers 1068a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_8k); 1069a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_8k, tc) 1070a8eb96d5SAlan Somers { 1071a8eb96d5SAlan Somers test_pipe(131072, 8192); 1072a8eb96d5SAlan Somers } 1073a8eb96d5SAlan Somers 1074a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(pipe_128k_128k); 1075a8eb96d5SAlan Somers ATF_TC_BODY(pipe_128k_128k, tc) 1076a8eb96d5SAlan Somers { 1077a8eb96d5SAlan Somers test_pipe(131072, 131072); 1078a8eb96d5SAlan Somers } 1079a8eb96d5SAlan Somers 1080a8eb96d5SAlan Somers 1081a8eb96d5SAlan Somers /* 1082a8eb96d5SAlan Somers * Test single-packet I/O with and without blocking, with symmetric buffers of 1083a8eb96d5SAlan Somers * various sizes 1084a8eb96d5SAlan Somers */ 1085a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k); 1086a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k, tc) 1087a8eb96d5SAlan Somers { 1088a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, true); 1089a8eb96d5SAlan Somers } 1090a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k); 1091a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k, tc) 1092a8eb96d5SAlan Somers { 1093a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, true); 1094a8eb96d5SAlan Somers } 1095a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k); 1096a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k, tc) 1097a8eb96d5SAlan Somers { 1098a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, true); 1099a8eb96d5SAlan Somers } 1100a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k); 1101a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k, tc) 1102a8eb96d5SAlan Somers { 1103a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, true); 1104a8eb96d5SAlan Somers } 1105a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k); 1106a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k, tc) 1107a8eb96d5SAlan Somers { 1108a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, true); 1109a8eb96d5SAlan Somers } 1110a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking); 1111a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_8k_nonblocking, tc) 1112a8eb96d5SAlan Somers { 1113a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(8 * 1024, false); 1114a8eb96d5SAlan Somers } 1115a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking); 1116a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_16k_nonblocking, tc) 1117a8eb96d5SAlan Somers { 1118a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(16 * 1024, false); 1119a8eb96d5SAlan Somers } 1120a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking); 1121a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_32k_nonblocking, tc) 1122a8eb96d5SAlan Somers { 1123a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(32 * 1024, false); 1124a8eb96d5SAlan Somers } 1125a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking); 1126a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_64k_nonblocking, tc) 1127a8eb96d5SAlan Somers { 1128a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(64 * 1024, false); 1129a8eb96d5SAlan Somers } 1130a8eb96d5SAlan Somers ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking); 1131a8eb96d5SAlan Somers ATF_TC_BODY(sendrecv_128k_nonblocking, tc) 1132a8eb96d5SAlan Somers { 1133a8eb96d5SAlan Somers test_sendrecv_symmetric_buffers(128 * 1024, false); 1134a8eb96d5SAlan Somers } 1135a8eb96d5SAlan Somers 1136a8eb96d5SAlan Somers 1137a8eb96d5SAlan Somers /* 1138a8eb96d5SAlan Somers * Main. 1139a8eb96d5SAlan Somers */ 1140a8eb96d5SAlan Somers 1141a8eb96d5SAlan Somers ATF_TP_ADD_TCS(tp) 1142a8eb96d5SAlan Somers { 1143a8eb96d5SAlan Somers /* Basic creation and connection tests */ 1144a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socket); 1145a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, create_socketpair); 1146a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_unbound); 1147a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, bind); 1148a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, listen_bound); 1149a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, connect); 1150a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, accept); 1151a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, fcntl_nonblock); 1152a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_buffers); 1153a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, resize_connected_buffers); 1154a8eb96d5SAlan Somers 1155a8eb96d5SAlan Somers /* Unthreaded I/O tests */ 1156a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv); 1157a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_nonblocking); 1158a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, send_recv_with_connect); 1159a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendto_recvfrom); 1160a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send); 1161a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, shutdown_send_sigpipe); 1162a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, emsgsize); 1163a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, emsgsize_nonblocking); 1164a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_8k); 1165a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_8k_128k); 1166a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_8k); 1167a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, eagain_128k_128k); 1168a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k); 1169a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k); 1170a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k); 1171a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k); 1172a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k); 1173a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking); 1174a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking); 1175a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking); 1176a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking); 1177a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking); 1178a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, rcvbuf_oversized); 1179a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k); 1180a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k); 1181a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k); 1182a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k); 1183a8eb96d5SAlan Somers 1184a8eb96d5SAlan Somers /* Threaded I/O tests with blocking sockets */ 1185a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_8k); 1186a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_8k_128k); 1187a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_8k); 1188a8eb96d5SAlan Somers ATF_TP_ADD_TC(tp, pipe_128k_128k); 1189a8eb96d5SAlan Somers 1190a8eb96d5SAlan Somers return atf_no_error(); 1191a8eb96d5SAlan Somers } 1192