1/*- 2 * Copyright (c) 2014 Spectra Logic Corporation. All rights reserved. 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions 5 * are met: 6 * 1. Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * 2. Redistributions in binary form must reproduce the above copyright --- 9 unchanged lines hidden (view full) --- 18 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 19 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 20 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 22 * SUCH DAMAGE. 23 */ 24 25#include <sys/cdefs.h> |
26__FBSDID("$FreeBSD: stable/10/tests/sys/kern/unix_seqpacket_test.c 263572 2014-03-21 22:43:00Z asomers $"); |
27 28#include <errno.h> 29#include <fcntl.h> 30#include <pthread.h> 31#include <signal.h> 32#include <sys/socket.h> 33#include <sys/un.h> 34 35#include <stdio.h> 36 37#include <atf-c.h> 38 39/* 40 * Helper functions 41 */ 42 43#define MIN(x, y) ((x) < (y) ? (x) : (y)) 44#define MAX(x, y) ((x) > (y) ? (x) : (y)) 45 |
46static void |
47do_socketpair(int *sv) 48{ 49 int s; 50 51 s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 52 ATF_REQUIRE_EQ(0, s); 53 ATF_REQUIRE(sv[0] >= 0); 54 ATF_REQUIRE(sv[1] >= 0); 55 ATF_REQUIRE(sv[0] != sv[1]); 56} 57 |
58static void |
59do_socketpair_nonblocking(int *sv) 60{ 61 int s; 62 63 s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv); 64 ATF_REQUIRE_EQ(0, s); 65 ATF_REQUIRE(sv[0] >= 0); 66 ATF_REQUIRE(sv[1] >= 0); 67 ATF_REQUIRE(sv[0] != sv[1]); 68 ATF_REQUIRE(-1 != fcntl(sv[0], F_SETFL, O_NONBLOCK)); 69 ATF_REQUIRE(-1 != fcntl(sv[1], F_SETFL, O_NONBLOCK)); 70} 71 72/* 73 * Returns a pair of sockets made the hard way: bind, listen, connect & accept 74 * @return const char* The path to the socket 75 */ |
76static const char* |
77mk_pair_of_sockets(int *sv) 78{ 79 struct sockaddr_un sun; 80 /* ATF's isolation mechanisms will guarantee uniqueness of this file */ 81 const char *path = "sock"; 82 int s, err, s2, s1; 83 84 s = socket(PF_LOCAL, SOCK_SEQPACKET, 0); --- 26 unchanged lines hidden (view full) --- 111 112 sv[0] = s1; 113 sv[1] = s2; 114 return (path); 115} 116 117static volatile sig_atomic_t got_sigpipe = 0; 118static void |
119shutdown_send_sigpipe_handler(int __unused x) |
120{ 121 got_sigpipe = 1; 122} 123 124/* 125 * Parameterized test function bodies 126 */ |
127static void |
128test_eagain(size_t sndbufsize, size_t rcvbufsize) 129{ 130 int i; 131 int sv[2]; 132 const size_t totalsize = (sndbufsize + rcvbufsize) * 2; 133 const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; |
134 const int numpkts = totalsize / pktsize; |
135 char sndbuf[pktsize]; |
136 ssize_t ssize; |
137 138 /* setup the socket pair */ 139 do_socketpair_nonblocking(sv); 140 /* Setup the buffers */ 141 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 142 sizeof(sndbufsize))); 143 ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 144 sizeof(rcvbufsize))); 145 146 bzero(sndbuf, pktsize); 147 /* Send data until we get EAGAIN */ |
148 for(i=0; i < numpkts; i++) { |
149 ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 150 if (ssize == -1) { 151 if (errno == EAGAIN) 152 atf_tc_pass(); 153 else { 154 perror("send"); 155 atf_tc_fail("send returned < 0 but not EAGAIN"); 156 } 157 } 158 } 159 atf_tc_fail("Never got EAGAIN"); 160} 161 |
162static void |
163test_sendrecv_symmetric_buffers(size_t bufsize, int blocking) { 164 int s; 165 int sv[2]; |
166 const ssize_t pktsize = bufsize / 2; |
167 char sndbuf[pktsize]; 168 char recv_buf[pktsize]; 169 ssize_t ssize, rsize; 170 171 /* setup the socket pair */ 172 if (blocking) 173 do_socketpair(sv); 174 else --- 21 unchanged lines hidden (view full) --- 196 if (rsize < 0) { 197 perror("recv"); 198 atf_tc_fail("recv returned < 0"); 199 } 200 ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd", 201 pktsize, rsize); 202} 203 |
204static void |
205test_pipe_simulator(size_t sndbufsize, size_t rcvbufsize) 206{ |
207 int num_sent, num_received; |
208 int sv[2]; |
209 const ssize_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; |
210 int numpkts; 211 char sndbuf[pktsize]; 212 char rcvbuf[pktsize]; 213 char comparebuf[pktsize]; 214 ssize_t ssize, rsize; 215 bool currently_sending = true; 216 217 /* setup the socket pair */ --- 108 unchanged lines hidden (view full) --- 326 d = memcmp(comparebuf, rcvbuf, td->pktsize); 327 ATF_CHECK_EQ_MSG(0, d, 328 "Received data miscompare on packet %d", i); 329 } 330 return (0); 331} 332 333 |
334static void |
335test_pipe(size_t sndbufsize, size_t rcvbufsize) 336{ 337 test_pipe_thread_data_t writer_data, reader_data; 338 pthread_t writer, reader; |
339 int sv[2]; 340 const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4; 341 int numpkts; 342 343 /* setup the socket pair */ 344 do_socketpair(sv); 345 /* Setup the buffers */ 346 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, --- 252 unchanged lines hidden (view full) --- 599 ls, lr, rs, rr); 600} 601 602 603/* send(2) and recv(2) a single short record */ 604ATF_TC_WITHOUT_HEAD(send_recv); 605ATF_TC_BODY(send_recv, tc) 606{ |
607 int sv[2]; 608 const int bufsize = 64; 609 const char *data = "data"; 610 char recv_buf[bufsize]; |
611 ssize_t datalen; |
612 ssize_t ssize, rsize; 613 614 /* setup the socket pair */ 615 do_socketpair(sv); 616 617 /* send and receive a small packet */ 618 datalen = strlen(data) + 1; /* +1 for the null */ 619 ssize = send(sv[0], data, datalen, MSG_EOR); --- 15 unchanged lines hidden (view full) --- 635 * According to the same spec, not all protocols are required to provide the 636 * source addres in recvfrom(2). 637 */ 638ATF_TC_WITHOUT_HEAD(sendto_recvfrom); 639ATF_TC_BODY(sendto_recvfrom, tc) 640{ 641 const char* path; 642 struct sockaddr_storage from; |
643 int sv[2]; 644 const int bufsize = 64; 645 const char *data = "data"; 646 char recv_buf[bufsize]; |
647 ssize_t datalen; |
648 ssize_t ssize, rsize; 649 socklen_t fromlen; 650 651 /* setup the socket pair */ 652 path = mk_pair_of_sockets(sv); 653 654 /* send and receive a small packet */ 655 datalen = strlen(data) + 1; /* +1 for the null */ --- 26 unchanged lines hidden (view full) --- 682 683/* 684 * send(2) and recv(2) a single short record with sockets created the 685 * traditional way, involving bind, listen, connect, and accept 686 */ 687ATF_TC_WITHOUT_HEAD(send_recv_with_connect); 688ATF_TC_BODY(send_recv_with_connect, tc) 689{ |
690 int sv[2]; 691 const int bufsize = 64; 692 const char *data = "data"; 693 char recv_buf[bufsize]; |
694 ssize_t datalen; |
695 ssize_t ssize, rsize; 696 697 mk_pair_of_sockets(sv); 698 699 /* send and receive a small packet */ 700 datalen = strlen(data) + 1; /* +1 for the null */ 701 ssize = send(sv[0], data, datalen, MSG_EOR); 702 if (ssize < 0) { --- 39 unchanged lines hidden (view full) --- 742 ssize = send(s, data, sizeof(data), MSG_EOR); 743 ATF_CHECK_EQ(1, got_sigpipe); 744} 745 746/* nonblocking send(2) and recv(2) a single short record */ 747ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 748ATF_TC_BODY(send_recv_nonblocking, tc) 749{ |
750 int sv[2]; 751 const int bufsize = 64; 752 const char *data = "data"; 753 char recv_buf[bufsize]; |
754 ssize_t datalen; |
755 ssize_t ssize, rsize; 756 757 /* setup the socket pair */ 758 do_socketpair_nonblocking(sv); 759 760 /* Verify that there is nothing to receive */ 761 rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 762 ATF_CHECK_EQ(EAGAIN, errno); --- 15 unchanged lines hidden (view full) --- 778 779/* 780 * We should get EMSGSIZE if we try to send a message larger than the socket 781 * buffer, with blocking sockets 782 */ 783ATF_TC_WITHOUT_HEAD(emsgsize); 784ATF_TC_BODY(emsgsize, tc) 785{ |
786 int sv[2]; 787 const size_t sndbufsize = 8192; 788 const size_t rcvbufsize = 8192; 789 const size_t pktsize = (sndbufsize + rcvbufsize) * 2; 790 char sndbuf[pktsize]; |
791 ssize_t ssize; |
792 793 /* setup the socket pair */ 794 do_socketpair(sv); 795 /* Setup the buffers */ 796 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 797 sizeof(sndbufsize))); 798 ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 799 sizeof(rcvbufsize))); --- 5 unchanged lines hidden (view full) --- 805 806/* 807 * We should get EMSGSIZE if we try to send a message larger than the socket 808 * buffer, with nonblocking sockets 809 */ 810ATF_TC_WITHOUT_HEAD(emsgsize_nonblocking); 811ATF_TC_BODY(emsgsize_nonblocking, tc) 812{ |
813 int sv[2]; 814 const size_t sndbufsize = 8192; 815 const size_t rcvbufsize = 8192; 816 const size_t pktsize = (sndbufsize + rcvbufsize) * 2; 817 char sndbuf[pktsize]; |
818 ssize_t ssize; |
819 820 /* setup the socket pair */ 821 do_socketpair_nonblocking(sv); 822 /* Setup the buffers */ 823 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 824 sizeof(sndbufsize))); 825 ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 826 sizeof(rcvbufsize))); --- 36 unchanged lines hidden (view full) --- 863 864/* 865 * nonblocking send(2) and recv(2) of several records, which should collectively 866 * fill up the send buffer but not the receive buffer 867 */ 868ATF_TC_WITHOUT_HEAD(rcvbuf_oversized); 869ATF_TC_BODY(rcvbuf_oversized, tc) 870{ |
871 int i; |
872 int sv[2]; |
873 const int pktsize = 1024; |
874 const size_t sndbufsize = 8192; 875 const size_t rcvbufsize = 131072; |
876 const size_t geometric_mean_bufsize = 32768; 877 const int numpkts = geometric_mean_bufsize / pktsize; |
878 char sndbuf[pktsize]; 879 char recv_buf[pktsize]; |
880 ssize_t ssize, rsize; 881 882 /* setup the socket pair */ 883 do_socketpair_nonblocking(sv); |
884 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 885 sizeof(sndbufsize))); 886 ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 887 sizeof(rcvbufsize))); |
888 889 /* 890 * Send and receive packets that are collectively greater than the send 891 * buffer, but less than the receive buffer 892 */ |
893 for (i=0; i < numpkts; i++) { |
894 /* Fill the buffer */ 895 memset(sndbuf, i, pktsize); 896 897 /* send the packet */ 898 ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 899 if (ssize < 0) { 900 perror("send"); 901 atf_tc_fail("send returned < 0"); --- 211 unchanged lines hidden --- |