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