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