1 /* Advanced tests for TCP and UDP sockets (LWIP) - by D.C. van Moolenbroek */
3 * This is a somewhat random collection of in-depth tests, complementing the
4 * more general functionality tests in test80 and test81. The overall test set
5 * is still by no means expected to be "complete." The subtests are in random
11 #include <sys/ioctl.h>
13 #include <sys/param.h>
15 #include <sys/queue.h>
16 #include <sys/socket.h>
17 #include <net/route.h>
18 #include <netinet/in.h>
19 #include <netinet/ip.h>
20 #include <netinet/ip_var.h>
21 #include <netinet/tcp.h>
22 #include <netinet/tcp_fsm.h>
23 #include <netinet/tcp_timer.h>
24 #include <netinet/tcp_var.h>
25 #include <netinet/udp.h>
26 #include <netinet6/in6_pcb.h>
27 #include <netinet6/in6_var.h>
28 #include <arpa/inet.h>
30 #include <machine/vmparam.h>
40 static const enum state tcp_states
[] = {
41 S_NEW
, S_N_SHUT_R
, S_BOUND
, S_LISTENING
,
42 S_L_SHUT_R
, S_L_SHUT_W
, S_L_SHUT_RW
, S_CONNECTING
,
43 S_C_SHUT_R
, S_C_SHUT_W
, S_C_SHUT_RW
, S_CONNECTED
,
44 S_ACCEPTED
, S_SHUT_R
, S_SHUT_W
, S_SHUT_RW
,
45 S_RSHUT_R
, S_RSHUT_W
, S_RSHUT_RW
, S_SHUT2_R
,
46 S_SHUT2_W
, S_SHUT2_RW
, S_PRE_EOF
, S_AT_EOF
,
47 S_POST_EOF
, S_PRE_SHUT_R
, S_EOF_SHUT_R
, S_POST_SHUT_R
,
48 S_PRE_SHUT_W
, S_EOF_SHUT_W
, S_POST_SHUT_W
, S_PRE_SHUT_RW
,
49 S_EOF_SHUT_RW
, S_POST_SHUT_RW
, S_PRE_RESET
, S_AT_RESET
,
50 S_POST_RESET
, S_FAILED
, S_POST_FAILED
53 static const int tcp_results
[][__arraycount(tcp_states
)] = {
55 -EINVAL
, -EINVAL
, -EINVAL
, -EAGAIN
,
56 -ECONNABORTED
, -ECONNABORTED
, -ECONNABORTED
, -EINVAL
,
57 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
58 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
59 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
60 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
61 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
62 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
63 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
64 -EINVAL
, -EINVAL
, -EINVAL
,
67 0, 0, -EINVAL
, -EINVAL
,
68 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
69 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
70 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
71 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
72 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
73 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
74 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
75 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
76 -EINVAL
, -EINVAL
, -EINVAL
,
79 -EINPROGRESS
, -EINPROGRESS
, -EINPROGRESS
, -EOPNOTSUPP
,
80 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EALREADY
,
81 -EALREADY
, -EINVAL
, -EINVAL
, -EISCONN
,
82 -EISCONN
, -EISCONN
, -EISCONN
, -EISCONN
,
83 -EISCONN
, -EISCONN
, -EISCONN
, -EISCONN
,
84 -EINVAL
, -EINVAL
, -EISCONN
, -EISCONN
,
85 -EISCONN
, -EISCONN
, -EISCONN
, -EISCONN
,
86 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
87 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
88 -EINVAL
, -EINVAL
, -EINVAL
,
91 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
92 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
93 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, 0,
96 -ENOTCONN
, -ENOTCONN
, 0, 0,
98 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
99 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
100 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
104 -EINVAL
, -EINVAL
, -EINVAL
, 0,
105 0, -EINVAL
, -EINVAL
, 0,
108 -EINVAL
, -EINVAL
, 0, 0,
110 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
111 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
112 -EINVAL
, -EINVAL
, -EINVAL
,
114 [C_GETSOCKOPT_ERR
] = {
123 0, 0, -ECONNRESET
, -ECONNRESET
,
126 [C_GETSOCKOPT_KA
] = {
138 [C_GETSOCKOPT_RB
] = {
140 -ECONNRESET
, -ECONNRESET
, -ECONNRESET
, 0,
141 0, -ECONNRESET
, -ECONNRESET
, 0,
144 -ECONNRESET
, -ECONNRESET
, 0, 0,
146 -ECONNRESET
, -ECONNRESET
, -ECONNRESET
, -ECONNRESET
,
147 -ECONNRESET
, -ECONNRESET
, -ECONNRESET
, -ECONNRESET
,
148 -ECONNRESET
, -ECONNRESET
, -ECONNRESET
,
165 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
166 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
167 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
168 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
169 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
170 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
171 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
172 -EINVAL
, -EINVAL
, -EINVAL
,
175 -ENOTCONN
, 0, -ENOTCONN
, -ENOTCONN
,
178 -EAGAIN
, 0, -EAGAIN
, 0,
183 0, 0, 1, -ECONNRESET
,
187 -ENOTCONN
, 0, -ENOTCONN
, -ENOTCONN
,
190 -EAGAIN
, 0, -EAGAIN
, 0,
195 0, 0, 1, -ECONNRESET
,
199 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
200 -EPIPE
, -EPIPE
, -EPIPE
, -EAGAIN
,
201 -EAGAIN
, -EPIPE
, -EPIPE
, 1,
202 1, 1, -EPIPE
, -EPIPE
,
204 -EPIPE
, -EPIPE
, 1, 1,
206 -EPIPE
, -EPIPE
, -EPIPE
, -EPIPE
,
207 -EPIPE
, -EPIPE
, -ECONNRESET
, -ECONNRESET
,
208 -EPIPE
, -ECONNREFUSED
, -EPIPE
,
211 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
212 -EPIPE
, -EPIPE
, -EPIPE
, -EAGAIN
,
213 -EAGAIN
, -EPIPE
, -EPIPE
, 1,
214 1, 1, -EPIPE
, -EPIPE
,
216 -EPIPE
, -EPIPE
, 1, 1,
218 -EPIPE
, -EPIPE
, -EPIPE
, -EPIPE
,
219 -EPIPE
, -EPIPE
, -ECONNRESET
, -ECONNRESET
,
220 -EPIPE
, -ECONNREFUSED
, -EPIPE
,
258 [C_SETSOCKOPT_BC
] = {
270 [C_SETSOCKOPT_KA
] = {
294 [C_SETSOCKOPT_RA
] = {
319 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, 0,
320 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, 0,
321 0, -ENOTCONN
, -ENOTCONN
, 0,
324 -ENOTCONN
, -ENOTCONN
, 0, 0,
326 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
327 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
328 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
331 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, 0,
332 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, 0,
333 0, -ENOTCONN
, -ENOTCONN
, 0,
336 -ENOTCONN
, -ENOTCONN
, 0, 0,
338 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
339 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
340 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
345 * Set up a TCP socket file descriptor in the requested state and pass it to
346 * socklib_sweep_call() along with local and remote addresses and their length.
349 tcp_sweep(int domain
, int type
, int protocol
, enum state state
, enum call call
)
351 struct sockaddr_in sinA
, sinB
, sinC
, sinD
;
352 struct sockaddr_in6 sin6A
, sin6B
, sin6C
, sin6D
;
353 struct sockaddr
*addrA
, *addrB
, *addrC
, *addrD
;
354 socklen_t addr_len
, len
;
358 int r
, fd
, fd2
, fd3
, tmpfd
, val
;
360 if (domain
== AF_INET
) {
361 memset(&sin6A
, 0, sizeof(sin6A
));
362 sinA
.sin_family
= domain
;
363 sinA
.sin_port
= htons(TEST_PORT_A
);
364 sinA
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
366 memcpy(&sinB
, &sinA
, sizeof(sinB
));
367 sinB
.sin_port
= htons(0);
369 memcpy(&sinC
, &sinA
, sizeof(sinC
));
370 sinC
.sin_addr
.s_addr
= inet_addr(TEST_BLACKHOLE_IPV4
);
372 memcpy(&sinD
, &sinA
, sizeof(sinD
));
373 sinD
.sin_port
= htons(TEST_PORT_B
);
375 addrA
= (struct sockaddr
*)&sinA
;
376 addrB
= (struct sockaddr
*)&sinB
;
377 addrC
= (struct sockaddr
*)&sinC
;
378 addrD
= (struct sockaddr
*)&sinD
;
379 addr_len
= sizeof(sinA
);
381 assert(domain
== AF_INET6
);
383 memset(&sin6A
, 0, sizeof(sin6A
));
384 sin6A
.sin6_family
= domain
;
385 sin6A
.sin6_port
= htons(TEST_PORT_A
);
386 memcpy(&sin6A
.sin6_addr
, &in6addr_loopback
,
387 sizeof(sin6A
.sin6_addr
));
389 memcpy(&sin6B
, &sin6A
, sizeof(sin6B
));
390 sin6B
.sin6_port
= htons(0);
392 memcpy(&sin6C
, &sin6A
, sizeof(sin6C
));
393 if (inet_pton(domain
, TEST_BLACKHOLE_IPV6
,
394 &sin6C
.sin6_addr
) != 1) e(0);
396 memcpy(&sin6D
, &sin6A
, sizeof(sin6D
));
397 sin6D
.sin6_port
= htons(TEST_PORT_B
);
399 addrA
= (struct sockaddr
*)&sin6A
;
400 addrB
= (struct sockaddr
*)&sin6B
;
401 addrC
= (struct sockaddr
*)&sin6C
;
402 addrD
= (struct sockaddr
*)&sin6D
;
403 addr_len
= sizeof(sin6A
);
406 /* Create a bound remote socket. */
407 if ((fd2
= socket(domain
, type
| SOCK_NONBLOCK
, protocol
)) < 0) e(0);
409 if (bind(fd2
, addrB
, addr_len
) != 0) e(0);
412 if (getsockname(fd2
, addrB
, &len
) != 0) e(0);
413 if (len
!= addr_len
) e(0);
415 if (listen(fd2
, 1) != 0) e(0);
422 if ((fd
= socket(domain
, type
| SOCK_NONBLOCK
,
423 protocol
)) < 0) e(0);
426 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &val
,
427 sizeof(val
)) != 0) e(0);
429 if (state
== S_N_SHUT_R
&& shutdown(fd
, SHUT_RD
)) e(0);
438 if ((fd
= socket(domain
, type
| SOCK_NONBLOCK
,
439 protocol
)) < 0) e(0);
442 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &val
,
443 sizeof(val
)) != 0) e(0);
445 if (bind(fd
, addrA
, addr_len
) != 0) e(0);
447 if (state
== S_BOUND
)
450 if (listen(fd
, 1) != 0) e(0);
453 case S_L_SHUT_R
: if (shutdown(fd
, SHUT_RD
)) e(0); break;
454 case S_L_SHUT_W
: if (shutdown(fd
, SHUT_WR
)) e(0); break;
455 case S_L_SHUT_RW
: if (shutdown(fd
, SHUT_RDWR
)) e(0); break;
465 if ((fd
= socket(domain
, type
| SOCK_NONBLOCK
,
466 protocol
)) < 0) e(0);
468 if (connect(fd
, addrC
, addr_len
) != -1) e(0);
469 if (errno
!= EINPROGRESS
) e(0);
472 case S_C_SHUT_R
: if (shutdown(fd
, SHUT_RD
)) e(0); break;
473 case S_C_SHUT_W
: if (shutdown(fd
, SHUT_WR
)) e(0); break;
474 case S_C_SHUT_RW
: if (shutdown(fd
, SHUT_RDWR
)) e(0); break;
491 if ((fd
= socket(domain
, type
| SOCK_NONBLOCK
,
492 protocol
)) < 0) e(0);
494 if (connect(fd
, addrB
, addr_len
) != -1) e(0);
495 if (errno
!= EINPROGRESS
) e(0);
497 /* Just to make sure, wait for the socket to be acceptable. */
500 if (select(fd2
+ 1, &fds
, NULL
, NULL
, NULL
) != 1) e(0);
503 if ((fd3
= accept(fd2
, addrC
, &len
)) < 0) e(0);
505 /* Just to make sure, wait for the socket to be connected. */
508 if (select(fd
+ 1, NULL
, &fds
, NULL
, NULL
) != 1) e(0);
512 case S_SHUT2_R
: if (shutdown(fd
, SHUT_RD
)) e(0); break;
514 case S_SHUT2_W
: if (shutdown(fd
, SHUT_WR
)) e(0); break;
516 case S_SHUT2_RW
: if (shutdown(fd
, SHUT_RDWR
)) e(0); break;
522 case S_SHUT2_R
: if (shutdown(fd3
, SHUT_RD
)) e(0); break;
524 case S_SHUT2_W
: if (shutdown(fd3
, SHUT_WR
)) e(0); break;
526 case S_SHUT2_RW
: if (shutdown(fd3
, SHUT_RDWR
)) e(0); break;
530 if (state
== S_ACCEPTED
) {
553 if ((fd
= socket(domain
, type
| SOCK_NONBLOCK
,
554 protocol
)) < 0) e(0);
556 if (connect(fd
, addrB
, addr_len
) != -1) e(0);
557 if (errno
!= EINPROGRESS
) e(0);
559 /* Just to make sure, wait for the socket to be acceptable. */
562 if (select(fd2
+ 1, &fds
, NULL
, NULL
, NULL
) != 1) e(0);
565 if ((fd3
= accept(fd2
, addrC
, &len
)) < 0) e(0);
567 if (send(fd3
, "", 1, 0) != 1) e(0);
576 if (setsockopt(fd3
, SOL_SOCKET
, SO_LINGER
, &l
,
577 sizeof(l
)) != 0) e(0);
584 if (close(fd3
) != 0) e(0);
587 /* Just to make sure, wait for the socket to receive data. */
590 if (select(fd
+ 1, &fds
, NULL
, NULL
, NULL
) != 1) e(0);
598 if (recv(fd
, buf
, sizeof(buf
), 0) != 1) e(0);
604 if (recv(fd
, buf
, sizeof(buf
), 0) != 1) e(0);
605 if (recv(fd
, buf
, sizeof(buf
), 0) != 0) e(0);
608 if (recv(fd
, buf
, sizeof(buf
), 0) != 1) e(0);
609 (void)recv(fd
, buf
, sizeof(buf
), 0);
618 case S_POST_SHUT_R
: if (shutdown(fd
, SHUT_RD
)) e(0); break;
621 case S_POST_SHUT_W
: if (shutdown(fd
, SHUT_WR
)) e(0); break;
624 case S_POST_SHUT_RW
: if (shutdown(fd
, SHUT_RDWR
)) e(0); break;
632 if ((fd
= socket(domain
, type
| SOCK_NONBLOCK
,
633 protocol
)) < 0) e(0);
635 if (connect(fd
, addrD
, addr_len
) != -1) e(0);
636 if (errno
!= EINPROGRESS
) e(0);
640 if (select(fd
+ 1, &fds
, NULL
, NULL
, NULL
) != 1) e(0);
642 if (state
== S_POST_FAILED
) {
643 if (recv(fd
, buf
, sizeof(buf
), 0) != -1) e(0);
644 if (errno
!= ECONNREFUSED
) e(0);
654 r
= socklib_sweep_call(call
, fd
, addrA
, addrB
, addr_len
);
656 if (close(fd
) != 0) e(0);
657 if (fd2
!= -1 && close(fd2
) != 0) e(0);
658 if (fd3
!= -1 && close(fd3
) != 0) e(0);
663 static const enum state udp_states
[] = {
664 S_NEW
, S_N_SHUT_R
, S_N_SHUT_W
, S_N_SHUT_RW
,
665 S_BOUND
, S_CONNECTED
, S_SHUT_R
, S_SHUT_W
,
666 S_SHUT_RW
, S_RSHUT_R
, S_RSHUT_W
, S_RSHUT_RW
,
667 S_SHUT2_R
, S_SHUT2_W
, S_SHUT2_RW
, S_PRE_RESET
,
668 S_AT_RESET
, S_POST_RESET
671 static const int udp_results
[][__arraycount(udp_states
)] = {
673 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
,
674 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
,
675 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
,
676 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
,
677 -EOPNOTSUPP
, -EOPNOTSUPP
,
681 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
682 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
683 -EINVAL
, -EINVAL
, -EINVAL
, -EINVAL
,
694 -ENOTCONN
, -ENOTCONN
, -ENOTCONN
, -ENOTCONN
,
707 [C_GETSOCKOPT_ERR
] = {
714 [C_GETSOCKOPT_KA
] = {
721 [C_GETSOCKOPT_RB
] = {
736 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
,
737 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
,
738 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
,
739 -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
, -EOPNOTSUPP
,
740 -EOPNOTSUPP
, -EOPNOTSUPP
,
743 -EAGAIN
, 0, -EAGAIN
, 0,
744 -EAGAIN
, -EAGAIN
, 0, -EAGAIN
,
745 0, -EAGAIN
, -EAGAIN
, -EAGAIN
,
750 -EAGAIN
, 0, -EAGAIN
, 0,
751 -EAGAIN
, -EAGAIN
, 0, -EAGAIN
,
752 0, -EAGAIN
, -EAGAIN
, -EAGAIN
,
757 -EDESTADDRREQ
, -EDESTADDRREQ
, -EPIPE
, -EPIPE
,
758 -EDESTADDRREQ
, 1, 1, -EPIPE
,
760 1, -EPIPE
, -EPIPE
, 1,
764 1, 1, -EPIPE
, -EPIPE
,
767 1, -EPIPE
, -EPIPE
, 1,
791 [C_SETSOCKOPT_BC
] = {
798 [C_SETSOCKOPT_KA
] = {
812 [C_SETSOCKOPT_RA
] = {
843 * Set up a UDP socket file descriptor in the requested state and pass it to
844 * socklib_sweep_call() along with local and remote addresses and their length.
847 udp_sweep(int domain
, int type
, int protocol
, enum state state
, enum call call
)
849 struct sockaddr_in sinA
, sinB
;
850 struct sockaddr_in6 sin6A
, sin6B
;
851 struct sockaddr
*addrA
, *addrB
;
856 if (domain
== AF_INET
) {
857 memset(&sinA
, 0, sizeof(sinA
));
858 sinA
.sin_family
= domain
;
859 sinA
.sin_port
= htons(TEST_PORT_A
);
860 sinA
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
862 memcpy(&sinB
, &sinA
, sizeof(sinB
));
863 sinB
.sin_port
= htons(TEST_PORT_B
);
865 addrA
= (struct sockaddr
*)&sinA
;
866 addrB
= (struct sockaddr
*)&sinB
;
867 addr_len
= sizeof(sinA
);
869 assert(domain
== AF_INET6
);
871 memset(&sin6A
, 0, sizeof(sin6A
));
872 sin6A
.sin6_family
= domain
;
873 sin6A
.sin6_port
= htons(TEST_PORT_A
);
874 memcpy(&sin6A
.sin6_addr
, &in6addr_loopback
,
875 sizeof(sin6A
.sin6_addr
));
877 memcpy(&sin6B
, &sin6A
, sizeof(sin6B
));
878 sin6B
.sin6_port
= htons(TEST_PORT_B
);
880 addrA
= (struct sockaddr
*)&sin6A
;
881 addrB
= (struct sockaddr
*)&sin6B
;
882 addr_len
= sizeof(sin6A
);
885 /* Create a bound remote socket. */
886 if ((fd2
= socket(domain
, type
| SOCK_NONBLOCK
, protocol
)) < 0) e(0);
888 if (bind(fd2
, addrB
, addr_len
) != 0) e(0);
895 if ((fd
= socket(domain
, type
| SOCK_NONBLOCK
,
896 protocol
)) < 0) e(0);
899 case S_N_SHUT_R
: if (shutdown(fd
, SHUT_RD
)) e(0); break;
900 case S_N_SHUT_W
: if (shutdown(fd
, SHUT_WR
)) e(0); break;
901 case S_N_SHUT_RW
: if (shutdown(fd
, SHUT_RDWR
)) e(0); break;
921 if ((fd
= socket(domain
, type
| SOCK_NONBLOCK
,
922 protocol
)) < 0) e(0);
924 if (bind(fd
, addrA
, addr_len
) != 0) e(0);
926 if (state
== S_BOUND
)
929 if (connect(fd
, addrB
, addr_len
) != 0) e(0);
933 case S_SHUT2_R
: if (shutdown(fd
, SHUT_RD
)) e(0); break;
935 case S_SHUT2_W
: if (shutdown(fd
, SHUT_WR
)) e(0); break;
937 case S_SHUT2_RW
: if (shutdown(fd
, SHUT_RDWR
)) e(0); break;
943 case S_SHUT2_R
: if (shutdown(fd2
, SHUT_RD
)) e(0); break;
945 case S_SHUT2_W
: if (shutdown(fd2
, SHUT_WR
)) e(0); break;
947 case S_SHUT2_RW
: if (shutdown(fd2
, SHUT_RDWR
)) e(0); break;
951 if (sendto(fd2
, "", 1, 0, addrA
, addr_len
) != 1) e(0);
953 if (close(fd2
) != 0) e(0);
956 if (state
!= S_PRE_RESET
) {
957 if (recv(fd
, buf
, sizeof(buf
), 0) != 1) e(0);
959 if (state
== S_POST_RESET
) {
960 (void)recv(fd
, buf
, sizeof(buf
), 0);
973 r
= socklib_sweep_call(call
, fd
, addrA
, addrB
, addr_len
);
975 if (close(fd
) != 0) e(0);
976 if (fd2
!= -1 && close(fd2
) != 0) e(0);
982 * Sweep test for socket calls versus socket states of TCP and UDP sockets.
990 socklib_sweep(AF_INET
, SOCK_STREAM
, 0, tcp_states
,
991 __arraycount(tcp_states
), (const int *)tcp_results
, tcp_sweep
);
993 socklib_sweep(AF_INET6
, SOCK_STREAM
, 0, tcp_states
,
994 __arraycount(tcp_states
), (const int *)tcp_results
, tcp_sweep
);
996 socklib_sweep(AF_INET
, SOCK_DGRAM
, 0, udp_states
,
997 __arraycount(udp_states
), (const int *)udp_results
, udp_sweep
);
999 socklib_sweep(AF_INET6
, SOCK_DGRAM
, 0, udp_states
,
1000 __arraycount(udp_states
), (const int *)udp_results
, udp_sweep
);
1003 #define F_SKIP -1 /* skip this entry */
1004 #define F_NO 0 /* binding or connecting should fail */
1005 #define F_YES 1 /* binding or connecting should succeed */
1006 #define F_DUAL 2 /* always fails on IPV6_V6ONLY sockets */
1007 #define F_ZONE 4 /* binding works only if a scope ID is given */
1008 #define F_UDP 8 /* do not test on TCP sockets */
1009 #define F_BAD 16 /* operations on this address result in EINVAL */
1011 static const struct {
1014 int may_connect
; /* UDP only */
1016 { "0.0.0.0", F_YES
, F_NO
},
1017 { "0.0.0.1", F_NO
, F_SKIP
},
1018 { "127.0.0.1", F_YES
, F_YES
},
1019 { "127.0.0.255", F_NO
, F_YES
},
1020 { "127.255.255.255", F_NO
, F_YES
},
1021 { "172.31.255.254", F_NO
, F_SKIP
}, /* may be valid.. */
1022 { "224.0.0.0", F_YES
| F_UDP
, F_SKIP
},
1023 { "239.255.255.255", F_YES
| F_UDP
, F_SKIP
},
1024 { "240.0.0.0", F_NO
, F_SKIP
},
1025 { "255.255.255.255", F_NO
, F_SKIP
},
1028 static const struct {
1031 int may_connect
; /* UDP only */
1033 { "::0", F_YES
, F_NO
},
1034 { "::1", F_YES
, F_YES
},
1035 { "::2", F_NO
, F_YES
},
1036 { "::127.0.0.1", F_NO
, F_YES
},
1037 { "::ffff:7f00:1", F_YES
| F_DUAL
, F_YES
| F_DUAL
},
1038 { "::ffff:7f00:ff", F_NO
| F_DUAL
, F_YES
| F_DUAL
},
1039 { "100::1", F_NO
, F_SKIP
},
1040 { "2fff:ffff::", F_NO
, F_SKIP
},
1041 { "fc00::1", F_NO
, F_SKIP
},
1042 { "fe00::1", F_NO
, F_SKIP
},
1043 { "fe80::1", F_YES
| F_ZONE
, F_YES
| F_ZONE
},
1044 { "fec0::1", F_NO
, F_SKIP
},
1045 { "ff01::1", F_YES
| F_ZONE
| F_UDP
, F_YES
| F_ZONE
},
1046 { "ff02::1", F_YES
| F_ZONE
| F_UDP
, F_YES
| F_ZONE
},
1047 { "ff02::2", F_YES
| F_ZONE
| F_UDP
, F_YES
| F_ZONE
},
1048 { "ff0e::1", F_YES
| F_UDP
, F_SKIP
},
1049 { "ffff::1", F_NO
| F_UDP
| F_BAD
, F_NO
| F_BAD
},
1053 * Test binding sockets of a particular type to various addresses.
1058 struct sockaddr_in sin
, lsin
;
1059 struct sockaddr_in6 sin6
, lsin6
;
1061 unsigned int i
, ifindex
;
1064 ifindex
= if_nametoindex(LOOPBACK_IFNAME
);
1066 /* Test binding IPv4 sockets to IPv4 addresses. */
1067 for (i
= 0; i
< __arraycount(addrs_v4
); i
++) {
1068 if (type
== SOCK_STREAM
&& (addrs_v4
[i
].may_bind
& F_UDP
))
1071 if ((fd
= socket(AF_INET
, type
, 0)) < 0) e(0);
1073 memset(&sin
, 0, sizeof(sin
));
1074 sin
.sin_family
= AF_INET
;
1075 if (inet_pton(AF_INET
, addrs_v4
[i
].addr
, &sin
.sin_addr
) != 1)
1078 r
= bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
));
1079 if (r
== -1 && errno
!= EADDRNOTAVAIL
) e(0);
1080 if (r
+ 1 != !!(addrs_v4
[i
].may_bind
& F_YES
)) e(0);
1083 if (getsockname(fd
, (struct sockaddr
*)&lsin
, &len
) != 0) e(0);
1084 if (lsin
.sin_len
!= sizeof(lsin
)) e(0);
1085 if (lsin
.sin_family
!= AF_INET
) e(0);
1087 if (lsin
.sin_port
== 0) e(0);
1088 if (lsin
.sin_addr
.s_addr
!= sin
.sin_addr
.s_addr
) e(0);
1090 if (lsin
.sin_port
!= 0) e(0);
1091 if (lsin
.sin_addr
.s_addr
!= htonl(INADDR_ANY
)) e(0);
1094 /* Rebinding never works; binding after a failed bind does. */
1095 sin
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
1096 r
= bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
));
1097 if (r
== -1 && errno
!= EINVAL
) e(0);
1098 if (!!r
!= !!(addrs_v4
[i
].may_bind
& F_YES
)) e(0);
1100 if (close(fd
) != 0) e(0);
1103 /* Test binding IPv6 sockets to IPv6 addresses. */
1104 for (i
= 0; i
< __arraycount(addrs_v6
); i
++) {
1105 if (type
== SOCK_STREAM
&& (addrs_v6
[i
].may_bind
& F_UDP
))
1108 /* Try without IPV6_V6ONLY. */
1109 if ((fd
= socket(AF_INET6
, type
, 0)) < 0) e(0);
1111 /* IPV6_V6ONLY may or may not be enabled by default.. */
1113 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
,
1114 sizeof(val
)) != 0) e(0);
1116 memset(&sin6
, 0, sizeof(sin6
));
1117 sin6
.sin6_family
= AF_INET6
;
1118 if (inet_pton(AF_INET6
, addrs_v6
[i
].addr
,
1119 &sin6
.sin6_addr
) != 1) e(0);
1121 if (addrs_v6
[i
].may_bind
& F_ZONE
) {
1122 if (bind(fd
, (struct sockaddr
*)&sin6
,
1123 sizeof(sin6
)) != -1) e(0);
1124 if (errno
!= EADDRNOTAVAIL
) e(0);
1126 sin6
.sin6_scope_id
= ifindex
;
1129 r
= bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
));
1131 if (addrs_v6
[i
].may_bind
& F_BAD
) {
1132 if (errno
!= EINVAL
) e(0);
1134 if (errno
!= EADDRNOTAVAIL
) e(0);
1137 if (r
+ 1 != !!(addrs_v6
[i
].may_bind
& F_YES
)) e(0);
1139 len
= sizeof(lsin6
);
1140 if (getsockname(fd
, (struct sockaddr
*)&lsin6
, &len
) != 0)
1142 if (lsin6
.sin6_len
!= sizeof(lsin6
)) e(0);
1143 if (lsin6
.sin6_family
!= AF_INET6
) e(0);
1145 if (lsin6
.sin6_port
== 0) e(0);
1146 if (memcmp(&lsin6
.sin6_addr
, &sin6
.sin6_addr
,
1147 sizeof(lsin6
.sin6_addr
))) e(0);
1148 if (lsin6
.sin6_scope_id
!=
1149 ((addrs_v6
[i
].may_bind
& F_ZONE
) ? ifindex
: 0))
1152 if (lsin6
.sin6_port
!= 0) e(0);
1153 if (!IN6_IS_ADDR_UNSPECIFIED(&lsin6
.sin6_addr
)) e(0);
1154 if (lsin6
.sin6_scope_id
!= 0) e(0);
1157 if (close(fd
) != 0) e(0);
1159 /* Try with IPV6_V6ONLY. */
1160 if ((fd
= socket(AF_INET6
, type
, 0)) < 0) e(0);
1163 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
,
1164 sizeof(val
)) != 0) e(0);
1166 r
= bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
));
1168 if (addrs_v6
[i
].may_bind
& (F_BAD
| F_DUAL
)) {
1169 if (errno
!= EINVAL
) e(0);
1171 if (errno
!= EADDRNOTAVAIL
) e(0);
1174 ((addrs_v6
[i
].may_bind
& (F_YES
| F_DUAL
)) == F_YES
)) e(0);
1176 if (close(fd
) != 0) e(0);
1179 /* Test binding an IPv6 socket to an IPv4 address. */
1180 if ((fd
= socket(AF_INET6
, type
, 0)) < 0) e(0);
1182 memset(&sin
, 0, sizeof(sin
));
1183 sin
.sin_family
= AF_INET
;
1184 sin
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
1186 if (bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != -1) e(0);
1187 if (errno
!= EINVAL
) e(0);
1189 assert(sizeof(sin
) <= sizeof(sin6
));
1190 memset(&sin6
, 0, sizeof(sin6
));
1191 memcpy(&sin6
, &sin
, sizeof(sin
));
1192 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1) e(0);
1193 if (errno
!= EAFNOSUPPORT
) e(0);
1195 if (close(fd
) != 0) e(0);
1197 /* Test binding an IPv4 socket to an IPv6 address. */
1198 if ((fd
= socket(AF_INET
, type
, 0)) < 0) e(0);
1200 memset(&sin6
, 0, sizeof(sin6
));
1201 sin6
.sin6_family
= AF_INET6
;
1202 memcpy(&sin6
.sin6_addr
, &in6addr_any
, sizeof(sin6
.sin6_addr
));
1204 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1) e(0);
1205 if (errno
!= EINVAL
) e(0);
1207 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin
)) != -1) e(0);
1208 if (errno
!= EAFNOSUPPORT
) e(0);
1210 if (close(fd
) != 0) e(0);
1212 /* Test binding a socket to AF_UNSPEC. */
1213 if ((fd
= socket(AF_INET
, type
, 0)) < 0) e(0);
1215 memset(&sin
, 0, sizeof(sin
));
1216 sin
.sin_family
= AF_UNSPEC
;
1218 if (bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != -1) e(0);
1219 if (errno
!= EAFNOSUPPORT
) e(0);
1221 if (close(fd
) != 0) e(0);
1225 * Test binding sockets to various addresses.
1233 sub91b(SOCK_STREAM
);
1239 * Test connecting TCP sockets to various addresses. We cannot test much here,
1240 * because we do not actually want this test to generate outgoing traffic. In
1241 * effect, we test calls that should fail only.
1246 struct sockaddr_in sin
;
1247 struct sockaddr_in6 sin6
;
1251 * Test connecting to address zero (0.0.0.0 and ::0). Apparently the
1252 * traditional BSD behavior for IPv4 is to use the first interface's
1253 * local address as destination instead, but our implementation does
1254 * not support that at this time: these 'any' addresses always result
1255 * in connection failures right away, hopefully eliminating some tricky
1256 * implementation boundary cases.
1258 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) e(0);
1260 memset(&sin
, 0, sizeof(sin
));
1261 sin
.sin_family
= AF_INET
;
1262 sin
.sin_port
= htons(TEST_PORT_A
);
1263 sin
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
1265 if (connect(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != -1) e(0);
1266 if (errno
!= EHOSTUNREACH
&& errno
!= ENETUNREACH
) e(0);
1268 if (close(fd
) != 0) e(0);
1270 if ((fd
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
1272 memset(&sin6
, 0, sizeof(sin6
));
1273 sin6
.sin6_family
= AF_INET6
;
1274 sin6
.sin6_port
= htons(TEST_PORT_A
);
1275 memcpy(&sin6
.sin6_addr
, &in6addr_any
, sizeof(sin6
.sin6_addr
));
1277 if (connect(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1) e(0);
1278 if (errno
!= EHOSTUNREACH
&& errno
!= ENETUNREACH
) e(0);
1280 if (close(fd
) != 0) e(0);
1283 * Test connecting to an IPv6-mapped IPv4 address on an IPv6 socket
1284 * with INET6_V6ONLY enabled.
1286 if ((fd
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
1289 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
1292 memset(&sin6
, 0, sizeof(sin6
));
1293 sin6
.sin6_family
= AF_INET6
;
1294 sin6
.sin6_port
= htons(TEST_PORT_A
);
1295 if (inet_pton(AF_INET6
, "::ffff:"LOOPBACK_IPV4
, &sin6
.sin6_addr
) != 1)
1298 if (connect(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1) e(0);
1299 if (errno
!= EINVAL
) e(0);
1301 if (close(fd
) != 0) e(0);
1303 /* Test connecting to an AF_UNSPEC address. */
1304 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) e(0);
1306 memset(&sin
, 0, sizeof(sin
));
1307 sin
.sin_family
= AF_UNSPEC
;
1309 if (connect(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != -1) e(0);
1310 if (errno
!= EAFNOSUPPORT
) e(0);
1312 if (close(fd
) != 0) e(0);
1314 /* Test connecting to port zero. */
1315 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
1317 memset(&sin
, 0, sizeof(sin
));
1318 sin
.sin_family
= AF_INET
;
1319 sin
.sin_port
= htons(0);
1320 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1322 if (connect(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != -1) e(0);
1323 if (errno
!= EADDRNOTAVAIL
) e(0);
1325 if (close(fd
) != 0) e(0);
1329 * Test connecting UDP sockets to various addresses.
1334 struct sockaddr_in sin
, rsin
;
1335 struct sockaddr_in6 sin6
, rsin6
;
1337 unsigned int i
, ifindex
;
1340 ifindex
= if_nametoindex(LOOPBACK_IFNAME
);
1342 /* Test connecting IPv4 sockets to IPv4 addresses. */
1343 for (i
= 0; i
< __arraycount(addrs_v4
); i
++) {
1344 if (addrs_v4
[i
].may_connect
== F_SKIP
)
1347 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
1349 memset(&sin
, 0, sizeof(sin
));
1350 sin
.sin_family
= AF_INET
;
1351 sin
.sin_port
= htons(TEST_PORT_A
);
1352 if (inet_pton(AF_INET
, addrs_v4
[i
].addr
, &sin
.sin_addr
) != 1)
1355 r
= connect(fd
, (struct sockaddr
*)&sin
, sizeof(sin
));
1356 if (r
+ 1 != !!(addrs_v4
[i
].may_connect
& F_YES
)) e(0);
1360 if (getpeername(fd
, (struct sockaddr
*)&rsin
,
1362 if (rsin
.sin_len
!= sizeof(rsin
)) e(0);
1363 if (rsin
.sin_family
!= AF_INET
) e(0);
1364 if (rsin
.sin_port
!= htons(TEST_PORT_A
)) e(0);
1365 if (rsin
.sin_addr
.s_addr
!= sin
.sin_addr
.s_addr
) e(0);
1367 if (getpeername(fd
, (struct sockaddr
*)&rsin
,
1369 if (errno
!= ENOTCONN
) e(0);
1372 sin
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
1373 r
= bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
));
1374 if (r
== -1 && errno
!= EINVAL
) e(0);
1375 if (r
+ 1 != !(addrs_v4
[i
].may_connect
& F_YES
)) e(0);
1377 if (close(fd
) != 0) e(0);
1380 /* Test connecting IPv6 sockets to IPv6 addresses. */
1381 for (i
= 0; i
< __arraycount(addrs_v6
); i
++) {
1382 if (addrs_v6
[i
].may_connect
== F_SKIP
)
1385 /* Try without IPV6_V6ONLY. */
1386 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
1388 /* IPV6_V6ONLY may or may not be enabled by default.. */
1390 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
,
1391 sizeof(val
)) != 0) e(0);
1393 memset(&sin6
, 0, sizeof(sin6
));
1394 sin6
.sin6_family
= AF_INET6
;
1395 sin6
.sin6_port
= htons(TEST_PORT_A
);
1396 if (inet_pton(AF_INET6
, addrs_v6
[i
].addr
,
1397 &sin6
.sin6_addr
) != 1) e(0);
1398 sin6
.sin6_scope_id
= ifindex
;
1400 r
= connect(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
));
1401 if (r
+ 1 != !!(addrs_v6
[i
].may_connect
& F_YES
)) e(0);
1403 len
= sizeof(rsin6
);
1405 if (getpeername(fd
, (struct sockaddr
*)&rsin6
,
1407 if (rsin6
.sin6_len
!= sizeof(rsin6
)) e(0);
1408 if (rsin6
.sin6_family
!= AF_INET6
) e(0);
1409 if (rsin6
.sin6_port
!= htons(TEST_PORT_A
)) e(0);
1410 if (memcmp(&rsin6
.sin6_addr
, &sin6
.sin6_addr
,
1411 sizeof(rsin6
.sin6_addr
))) e(0);
1412 if (rsin6
.sin6_scope_id
!=
1413 ((addrs_v6
[i
].may_connect
& F_ZONE
) ? ifindex
: 0))
1416 if (getpeername(fd
, (struct sockaddr
*)&rsin
,
1418 if (errno
!= ENOTCONN
) e(0);
1421 if (close(fd
) != 0) e(0);
1423 /* Try with IPV6_V6ONLY. */
1424 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
1427 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
,
1428 sizeof(val
)) != 0) e(0);
1430 r
= connect(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
));
1431 if (r
== -1 && errno
!= EINVAL
&& errno
!= EHOSTUNREACH
) e(0);
1433 ((addrs_v6
[i
].may_connect
& (F_YES
| F_DUAL
)) == F_YES
))
1436 if (close(fd
) != 0) e(0);
1439 /* Test connecting an IPv6 socket to an IPv4 address. */
1440 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
1442 memset(&sin
, 0, sizeof(sin
));
1443 sin
.sin_family
= AF_INET
;
1444 sin
.sin_port
= htons(TEST_PORT_A
);
1445 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1447 if (connect(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != -1) e(0);
1448 if (errno
!= EINVAL
) e(0);
1450 assert(sizeof(sin
) <= sizeof(sin6
));
1451 memset(&sin6
, 0, sizeof(sin6
));
1452 memcpy(&sin6
, &sin
, sizeof(sin
));
1453 if (connect(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1) e(0);
1454 if (errno
!= EAFNOSUPPORT
) e(0);
1456 if (close(fd
) != 0) e(0);
1458 /* Test connecting an IPv4 socket to an IPv6 address. */
1459 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
1461 memset(&sin6
, 0, sizeof(sin6
));
1462 sin6
.sin6_family
= AF_INET6
;
1463 memcpy(&sin6
.sin6_addr
, &in6addr_any
, sizeof(sin6
.sin6_addr
));
1465 if (connect(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1) e(0);
1466 if (errno
!= EINVAL
) e(0);
1468 if (connect(fd
, (struct sockaddr
*)&sin6
, sizeof(sin
)) != -1) e(0);
1469 if (errno
!= EAFNOSUPPORT
) e(0);
1471 if (close(fd
) != 0) e(0);
1473 /* Test unconnecting a socket using AF_UNSPEC. */
1474 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
1476 memset(&sin
, 0, sizeof(sin
));
1477 sin
.sin_family
= AF_INET
;
1478 sin
.sin_port
= htons(TEST_PORT_A
);
1479 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1481 if (connect(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
1483 memset(&sin
, 0, sizeof(sin
));
1484 sin
.sin_family
= AF_UNSPEC
;
1486 if (connect(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
1489 if (getpeername(fd
, (struct sockaddr
*)&rsin
, &len
) != -1) e(0);
1490 if (errno
!= ENOTCONN
) e(0);
1492 if (close(fd
) != 0) e(0);
1494 /* Test connecting to port zero. */
1495 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
1497 memset(&sin
, 0, sizeof(sin
));
1498 sin
.sin_family
= AF_INET
;
1499 sin
.sin_port
= htons(0);
1500 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1502 if (connect(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != -1) e(0);
1503 if (errno
!= EADDRNOTAVAIL
) e(0);
1505 if (close(fd
) != 0) e(0);
1509 * Test connecting sockets to various addresses.
1523 * Test binding with IPv4/IPv6 on the same port for the given socket type.
1528 struct sockaddr_in sin
;
1529 struct sockaddr_in6 sin6
;
1530 int r
, fd
, fd2
, val
;
1532 if ((fd
= socket(AF_INET
, type
, 0)) < 0) e(0);
1534 memset(&sin
, 0, sizeof(sin
));
1535 sin
.sin_family
= AF_INET
;
1536 sin
.sin_port
= htons(TEST_PORT_A
);
1537 sin
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
1539 if (bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
1541 /* IPv4 bound; IPv6 bind without IPV6_V6ONLY may or may not work. */
1542 if ((fd2
= socket(AF_INET6
, type
, 0)) < 0) e(0);
1545 if (setsockopt(fd2
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
1548 memset(&sin6
, 0, sizeof(sin6
));
1549 sin6
.sin6_family
= AF_INET6
;
1550 sin6
.sin6_port
= htons(TEST_PORT_A
);
1551 memcpy(&sin6
.sin6_addr
, &in6addr_any
, sizeof(sin6
.sin6_addr
));
1553 r
= bind(fd2
, (struct sockaddr
*)&sin6
, sizeof(sin6
));
1554 if (r
== -1 && errno
!= EADDRINUSE
) e(0);
1556 if (close(fd2
) != 0) e(0);
1558 /* IPv4 bound; IPv6 bind with IPV6_V6ONLY should work. */
1559 if ((fd2
= socket(AF_INET6
, type
, 0)) < 0) e(0);
1562 if (setsockopt(fd2
, SOL_SOCKET
, SO_REUSEADDR
, &val
, sizeof(val
)) != 0)
1564 if (setsockopt(fd2
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
1567 memset(&sin6
, 0, sizeof(sin6
));
1568 sin6
.sin6_family
= AF_INET6
;
1569 sin6
.sin6_port
= htons(TEST_PORT_A
);
1570 memcpy(&sin6
.sin6_addr
, &in6addr_loopback
, sizeof(sin6
.sin6_addr
));
1572 if (bind(fd2
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
1574 if (close(fd2
) != 0) e(0);
1575 if (close(fd
) != 0) e(0);
1577 /* IPv6 bound with IPV6_V6ONLY; IPv4 bind may or may not work. */
1578 if ((fd
= socket(AF_INET6
, type
, 0)) < 0) e(0);
1580 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &val
, sizeof(val
)) != 0)
1583 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
1586 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
1588 if ((fd2
= socket(AF_INET
, type
, 0)) < 0) e(0);
1590 r
= bind(fd2
, (struct sockaddr
*)&sin
, sizeof(sin
));
1591 if (r
== -1 && errno
!= EADDRINUSE
) e(0);
1593 if (close(fd2
) != 0) e(0);
1594 if (close(fd
) != 0) e(0);
1596 /* IPv6 bound with IPV6_V6ONLY; IPv4 bind should work. */
1597 if ((fd
= socket(AF_INET6
, type
, 0)) < 0) e(0);
1600 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &val
, sizeof(val
)) != 0)
1602 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
1605 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
1607 if ((fd2
= socket(AF_INET
, type
, 0)) < 0) e(0);
1609 if (bind(fd2
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
1611 if (close(fd2
) != 0) e(0);
1612 if (close(fd
) != 0) e(0);
1616 * Test binding with IPv4/IPv6 on the same port, and IPV6_V6ONLY.
1624 sub91d(SOCK_STREAM
);
1630 * Test sending large and small UDP packets.
1635 struct sockaddr_in sin
;
1640 int r
, fd
, fd2
, val
;
1644 if ((buf
= malloc(65536)) == NULL
) e(0);
1646 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
1648 memset(&sin
, 0, sizeof(sin
));
1649 sin
.sin_family
= AF_INET
;
1650 sin
.sin_port
= htons(TEST_PORT_A
);
1651 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1653 if (bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
1656 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &val
, sizeof(val
)) != 0)
1659 if ((fd2
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
1662 * A maximum send buffer size of a full packet size's worth may always
1663 * be set, although this is not necessarily the actual maximum.
1666 if (setsockopt(fd2
, SOL_SOCKET
, SO_SNDBUF
, &val
, sizeof(val
)) != 0)
1669 /* Find the largest possible packet size that can actually be sent. */
1670 for (i
= 0; i
< val
; i
+= sizeof(int)) {
1672 memcpy(&buf
[i
], &j
, sizeof(j
));
1675 for (val
= 65536; val
> 0; val
--) {
1676 if ((r
= sendto(fd2
, buf
, val
, 0, (struct sockaddr
*)&sin
,
1677 sizeof(sin
))) == val
)
1680 if (errno
!= EMSGSIZE
) e(0);
1683 if (val
!= 65535 - sizeof(struct udphdr
) - sizeof(struct ip
)) e(0);
1685 memset(buf
, 0, val
);
1688 memset(&iov
, 0, sizeof(iov
));
1690 iov
.iov_len
= val
+ 1;
1691 memset(&msg
, 0, sizeof(msg
));
1694 if (recvmsg(fd
, &msg
, 0) != val
) e(0);
1695 if (msg
.msg_flags
!= 0) e(0);
1697 for (i
= 0; i
< val
; i
+= sizeof(int)) {
1699 if (memcmp(&buf
[i
], &j
, MIN(sizeof(j
), val
- i
))) e(0);
1701 if (buf
[val
] != 'X') e(0);
1703 if (sendto(fd2
, buf
, val
, 0, (struct sockaddr
*)&sin
, sizeof(sin
)) !=
1707 * Make sure that there are no off-by-one errors in the receive code,
1708 * and that MSG_TRUNC is set (only) when not the whole packet was
1711 memset(&iov
, 0, sizeof(iov
));
1714 memset(&msg
, 0, sizeof(msg
));
1717 if (recvmsg(fd
, &msg
, 0) != val
) e(0);
1718 if (msg
.msg_flags
!= 0) e(0);
1720 if (sendto(fd2
, buf
, val
, 0, (struct sockaddr
*)&sin
, sizeof(sin
)) !=
1725 memset(&iov
, 0, sizeof(iov
));
1727 iov
.iov_len
= val
- 1;
1728 memset(&msg
, 0, sizeof(msg
));
1731 if (recvmsg(fd
, &msg
, 0) != val
- 1) e(0);
1732 if (msg
.msg_flags
!= MSG_TRUNC
) e(0);
1734 for (i
= 0; i
< val
- 1; i
+= sizeof(int)) {
1736 if (memcmp(&buf
[i
], &j
, MIN(sizeof(j
), val
- 1 - i
))) e(0);
1738 if (buf
[val
- 1] != 'Y') e(0);
1740 if (sendto(fd2
, buf
, val
, 0, (struct sockaddr
*)&sin
, sizeof(sin
)) !=
1745 memset(&iov
, 0, sizeof(iov
));
1748 memset(&msg
, 0, sizeof(msg
));
1751 if (recvmsg(fd
, &msg
, 0) != 0) e(0);
1752 if (msg
.msg_flags
!= MSG_TRUNC
) e(0);
1753 if (buf
[0] != 'Z') e(0);
1755 /* Make sure that zero-sized packets can be sent and received. */
1756 if (sendto(fd2
, buf
, 0, 0, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0)
1760 * Note how we currently assume that packets sent over localhost will
1761 * arrive immediately, so that we can use MSG_DONTWAIT to avoid that
1764 memset(&msg
, 0, sizeof(msg
));
1767 if (recvmsg(fd
, &msg
, MSG_DONTWAIT
) != 0) e(0);
1768 if (msg
.msg_flags
!= 0) e(0);
1769 if (buf
[0] != 'Z') e(0);
1771 if (recv(fd
, buf
, val
, MSG_DONTWAIT
) != -1) e(0);
1772 if (errno
!= EWOULDBLOCK
) e(0);
1775 * When sending lots of small packets, ensure that fewer packets arrive
1776 * than we sent. This sounds weird, but we cannot actually check the
1777 * internal TCP/IP buffer granularity and yet we want to make sure that
1778 * the receive queue is measured in terms of buffers rather than packet
1779 * sizes. In addition, we check that older packets are favored,
1780 * instead discarding new ones when the receive buffer is full.
1782 for (i
= 0; i
< 65536 / sizeof(j
); i
++) {
1784 if (sendto(fd2
, &j
, sizeof(j
), 0, (struct sockaddr
*)&sin
,
1785 sizeof(sin
)) != sizeof(j
)) e(0);
1788 for (i
= 0; i
< 1025; i
++) {
1789 r
= recv(fd
, &j
, sizeof(j
), MSG_DONTWAIT
);
1791 if (errno
!= EWOULDBLOCK
) e(0);
1794 if (r
!= sizeof(j
)) e(0);
1797 if (i
== 1025) e(0);
1799 if (close(fd2
) != 0) e(0);
1800 if (close(fd
) != 0) e(0);
1806 * Test setting and retrieving IP-level options for the given socket type. For
1807 * TCP sockets, we cannot test whether they are actually applied, but for UDP
1808 * sockets, we do a more complete test later on.
1816 /* Test IPv4 first. */
1817 if ((fd
= socket(AF_INET
, type
, 0)) < 0) e(0);
1819 /* Test obtaining the default TOS and TTL values. */
1821 if (getsockopt(fd
, IPPROTO_IP
, IP_TOS
, &val
, &len
) != 0) e(0);
1822 if (len
!= sizeof(val
)) e(0);
1826 if (getsockopt(fd
, IPPROTO_IP
, IP_TTL
, &def
, &len
) != 0) e(0);
1827 if (len
!= sizeof(def
)) e(0);
1828 if (def
< 16 || def
> UINT8_MAX
) e(0);
1830 /* Test changing the TOS field. */
1831 for (val
= 0; val
<= UINT8_MAX
; val
++)
1832 if (setsockopt(fd
, IPPROTO_IP
, IP_TOS
, &val
, sizeof(val
)) != 0)
1834 val
= -1; /* not a special value for IPv4 */
1835 if (setsockopt(fd
, IPPROTO_IP
, IP_TOS
, &val
, sizeof(val
)) != -1) e(0);
1836 if (errno
!= EINVAL
) e(0);
1837 val
= UINT8_MAX
+ 1;
1838 if (setsockopt(fd
, IPPROTO_IP
, IP_TOS
, &val
, sizeof(val
)) != -1) e(0);
1839 if (errno
!= EINVAL
) e(0);
1842 if (getsockopt(fd
, IPPROTO_IP
, IP_TOS
, &val
, &len
) != 0) e(0);
1843 if (len
!= sizeof(val
)) e(0);
1844 if (val
!= UINT8_MAX
) e(0);
1846 /* Test changing the TTL field. */
1847 for (val
= 0; val
<= UINT8_MAX
; val
++)
1848 if (setsockopt(fd
, IPPROTO_IP
, IP_TTL
, &val
, sizeof(val
)) != 0)
1851 if (setsockopt(fd
, IPPROTO_IP
, IP_TTL
, &val
, sizeof(val
)) != 0) e(0);
1852 val
= -1; /* not a special value for IPv4 */
1853 if (setsockopt(fd
, IPPROTO_IP
, IP_TTL
, &val
, sizeof(val
)) != -1) e(0);
1854 if (errno
!= EINVAL
) e(0);
1855 val
= UINT8_MAX
+ 1;
1856 if (setsockopt(fd
, IPPROTO_IP
, IP_TTL
, &val
, sizeof(val
)) != -1) e(0);
1857 if (errno
!= EINVAL
) e(0);
1860 if (getsockopt(fd
, IPPROTO_IP
, IP_TTL
, &val
, &len
) != 0) e(0);
1861 if (len
!= sizeof(val
)) e(0);
1862 if (val
!= 39) e(0);
1864 /* It must not be possible to set IPv6 options on IPv4 sockets. */
1866 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, sizeof(val
)) != -1)
1868 if (errno
!= ENOPROTOOPT
) e(0);
1869 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
,
1870 sizeof(val
)) != -1) e(0);
1871 if (errno
!= ENOPROTOOPT
) e(0);
1874 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, &len
) != -1) e(0);
1875 if (errno
!= ENOPROTOOPT
) e(0);
1876 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
, &len
) != -1)
1878 if (errno
!= ENOPROTOOPT
) e(0);
1880 if (close(fd
) != 0) e(0);
1882 /* Test IPv6 next. */
1883 if ((fd
= socket(AF_INET6
, type
, 0)) < 0) e(0);
1885 /* Test obtaining the default TCLASS and HOPS values. */
1887 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, &len
) != 0) e(0);
1888 if (len
!= sizeof(val
)) e(0);
1892 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &def
, &len
) != 0)
1894 if (len
!= sizeof(def
)) e(0);
1895 if (def
< 16 || def
> UINT8_MAX
) e(0);
1897 /* Test changing the TCLASS field. */
1898 for (val
= 0; val
<= UINT8_MAX
; val
++)
1899 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
,
1900 sizeof(val
)) != 0) e(0);
1902 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, sizeof(val
)) != -1)
1904 if (errno
!= EINVAL
) e(0);
1905 val
= UINT8_MAX
+ 1;
1906 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, sizeof(val
)) != -1)
1908 if (errno
!= EINVAL
) e(0);
1911 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, &len
) != 0) e(0);
1912 if (len
!= sizeof(val
)) e(0);
1913 if (val
!= UINT8_MAX
) e(0);
1915 val
= -1; /* reset to default */
1916 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, sizeof(val
)) != 0)
1920 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, &len
) != 0) e(0);
1921 if (len
!= sizeof(val
)) e(0);
1924 /* Test changing the HOPS field. */
1925 for (val
= 0; val
<= UINT8_MAX
; val
++)
1926 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
,
1927 sizeof(val
)) != 0) e(0);
1929 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
,
1930 sizeof(val
)) != 0) e(0);
1932 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
,
1933 sizeof(val
)) != -1) e(0);
1934 if (errno
!= EINVAL
) e(0);
1935 val
= UINT8_MAX
+ 1;
1936 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
,
1937 sizeof(val
)) != -1) e(0);
1938 if (errno
!= EINVAL
) e(0);
1941 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
, &len
) != 0)
1943 if (len
!= sizeof(val
)) e(0);
1944 if (val
!= 49) e(0);
1946 val
= -1; /* reset to default */
1947 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
,
1948 sizeof(val
)) != 0) e(0);
1951 if (getsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
, &len
) != 0)
1953 if (len
!= sizeof(val
)) e(0);
1954 if (val
!= def
) e(0);
1956 /* It must not be possible to set IPv4 options on IPv6 sockets. */
1958 if (setsockopt(fd
, IPPROTO_IP
, IP_TOS
, &val
, sizeof(val
)) != -1) e(0);
1959 if (errno
!= ENOPROTOOPT
) e(0);
1960 if (setsockopt(fd
, IPPROTO_IP
, IP_TTL
, &val
, sizeof(val
)) != -1) e(0);
1961 if (errno
!= ENOPROTOOPT
) e(0);
1964 if (getsockopt(fd
, IPPROTO_IP
, IP_TOS
, &val
, &len
) != -1) e(0);
1965 if (errno
!= ENOPROTOOPT
) e(0);
1966 if (getsockopt(fd
, IPPROTO_IP
, IP_TTL
, &val
, &len
) != -1) e(0);
1967 if (errno
!= ENOPROTOOPT
) e(0);
1969 if (close(fd
) != 0) e(0);
1973 * Test setting and retrieving IP-level options.
1981 sub91f(SOCK_STREAM
);
1987 * Test setting and retrieving IP-level options on UDP sockets and packets.
1988 * As part of this, ensure that the maximum set of supported control options
1989 * can be both sent and received, both for IPv4 and IPv6. Any options that are
1990 * newly added to the service and may be combined with the existing ones should
1991 * be added to this subtest as well. The control data handling code is shared
1992 * between UDP and RAW, so there is no need to repeat this test for the latter.
1997 struct sockaddr_in6 sin6
;
1998 struct sockaddr_in sin
;
2001 struct cmsghdr
*cmsg
, cmsg2
;
2002 struct in_pktinfo ipi
;
2003 struct in6_pktinfo ipi6
;
2004 unsigned int ifindex
;
2007 struct cmsghdr cmsg
;
2012 int fd
, fd2
, val
, seen_tos
, seen_ttl
, seen_pktinfo
;
2016 ifindex
= if_nametoindex(LOOPBACK_IFNAME
);
2017 if (ifindex
== 0) e(0);
2019 if ((fd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
2021 memset(&sin
, 0, sizeof(sin
));
2022 sin
.sin_family
= AF_INET
;
2023 sin
.sin_port
= htons(TEST_PORT_A
);
2024 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
2026 if (bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
2029 /* Strangely, IP_RECVTOS is not a thing.. */
2030 if (setsockopt(fd
, IPPROTO_IP
, IP_RECVTTL
, &val
, sizeof(val
)) != 0)
2032 if (setsockopt(fd
, IPPROTO_IP
, IP_RECVPKTINFO
, &val
, sizeof(val
)) != 0)
2035 if ((fd2
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
2041 control
.cmsg
.cmsg_len
= CMSG_LEN(sizeof(val
));
2042 control
.cmsg
.cmsg_level
= IPPROTO_IP
;
2043 control
.cmsg
.cmsg_type
= IP_TTL
;
2044 memcpy(CMSG_DATA(&control
.cmsg
), &val
, sizeof(val
));
2046 memset(&msg
, 0, sizeof(msg
));
2047 msg
.msg_name
= (struct sockaddr
*)&sin
;
2048 msg
.msg_namelen
= sizeof(sin
);
2051 msg
.msg_control
= control
.buf
;
2052 msg
.msg_controllen
= control
.cmsg
.cmsg_len
;
2054 if (sendmsg(fd2
, &msg
, 0) != 1) e(0);
2057 iov
.iov_len
= sizeof(buf
);
2059 memset(&msg
, 0, sizeof(msg
));
2062 msg
.msg_control
= control
.buf
;
2063 msg
.msg_controllen
= sizeof(control
);
2065 if (recvmsg(fd
, &msg
, 0) != 1) e(0);
2066 if (buf
[0] != 'A') e(0);
2068 seen_ttl
= seen_pktinfo
= 0;
2069 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
!= NULL
;
2070 cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
2071 if (cmsg
->cmsg_level
!= IPPROTO_IP
) e(0);
2072 switch (cmsg
->cmsg_type
) {
2074 /* The odd one out, using a uint8_t.. */
2075 if (seen_ttl
++) e(0);
2076 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(byte
))) e(0);
2077 memcpy(&byte
, CMSG_DATA(cmsg
), sizeof(byte
));
2078 if (byte
!= 39) e(0);
2081 if (seen_pktinfo
++) e(0);
2082 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(ipi
))) e(0);
2083 memcpy(&ipi
, CMSG_DATA(cmsg
), sizeof(ipi
));
2084 if (ipi
.ipi_addr
.s_addr
!= sin
.sin_addr
.s_addr
) e(0);
2085 if (ipi
.ipi_ifindex
!= ifindex
) e(0);
2091 if (!seen_ttl
) e(0);
2092 if (!seen_pktinfo
) e(0);
2094 /* Test that we can provide all supported IPv4 options at once. */
2099 control
.cmsg
.cmsg_len
= CMSG_LEN(sizeof(val
));
2100 control
.cmsg
.cmsg_level
= IPPROTO_IP
;
2101 control
.cmsg
.cmsg_type
= IP_TOS
;
2102 memcpy(CMSG_DATA(&control
.cmsg
), &val
, sizeof(val
));
2104 size
= CMSG_SPACE(sizeof(val
));
2106 if ((cmsg
= CMSG_NXTHDR(&msg
, &control
.cmsg
)) == NULL
) e(0);
2108 cmsg2
.cmsg_len
= CMSG_LEN(sizeof(val
));
2109 cmsg2
.cmsg_level
= IPPROTO_IP
;
2110 cmsg2
.cmsg_type
= IP_TTL
;
2111 memcpy(cmsg
, &cmsg2
, sizeof(cmsg2
));
2112 memcpy(CMSG_DATA(cmsg
), &val
, sizeof(val
));
2114 size
+= CMSG_SPACE(sizeof(val
));
2116 memset(&msg
, 0, sizeof(msg
));
2117 msg
.msg_name
= (struct sockaddr
*)&sin
;
2118 msg
.msg_namelen
= sizeof(sin
);
2121 msg
.msg_control
= control
.buf
;
2122 msg
.msg_controllen
= size
;
2124 if (sendmsg(fd2
, &msg
, 0) != 1) e(0);
2127 iov
.iov_len
= sizeof(buf
);
2129 memset(&msg
, 0, sizeof(msg
));
2132 msg
.msg_control
= control
.buf
;
2133 msg
.msg_controllen
= sizeof(control
);
2135 if (recvmsg(fd
, &msg
, 0) != 1) e(0);
2136 if (buf
[0] != 'B') e(0);
2138 /* Check just the TTL this time. */
2140 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
!= NULL
;
2141 cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
2142 if (cmsg
->cmsg_level
!= IPPROTO_IP
) e(0);
2143 if (cmsg
->cmsg_type
== IP_TTL
) {
2144 /* The odd one out, using a uint8_t.. */
2145 if (seen_ttl
++) e(0);
2146 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(byte
))) e(0);
2147 memcpy(&byte
, CMSG_DATA(cmsg
), sizeof(byte
));
2148 if (byte
!= 41) e(0);
2151 if (!seen_ttl
) e(0);
2153 if (close(fd2
) != 0) e(0);
2154 if (close(fd
) != 0) e(0);
2156 /* That was IPv4, onto IPv6.. */
2157 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
2159 memset(&sin6
, 0, sizeof(sin6
));
2160 sin6
.sin6_family
= AF_INET6
;
2161 sin6
.sin6_port
= htons(TEST_PORT_A
);
2162 memcpy(&sin6
.sin6_addr
, &in6addr_loopback
, sizeof(sin6
.sin6_addr
));
2164 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
2167 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVTCLASS
, &val
,
2168 sizeof(val
)) != 0) e(0);
2169 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVHOPLIMIT
, &val
,
2170 sizeof(val
)) != 0) e(0);
2171 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &val
,
2172 sizeof(val
)) != 0) e(0);
2174 if ((fd2
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
2177 if (setsockopt(fd2
, IPPROTO_IPV6
, IPV6_TCLASS
, &val
, sizeof(val
)) != 0)
2184 control
.cmsg
.cmsg_len
= CMSG_LEN(sizeof(val
));
2185 control
.cmsg
.cmsg_level
= IPPROTO_IPV6
;
2186 control
.cmsg
.cmsg_type
= IPV6_HOPLIMIT
;
2187 memcpy(CMSG_DATA(&control
.cmsg
), &val
, sizeof(val
));
2189 memset(&msg
, 0, sizeof(msg
));
2190 msg
.msg_name
= (struct sockaddr
*)&sin6
;
2191 msg
.msg_namelen
= sizeof(sin6
);
2194 msg
.msg_control
= control
.buf
;
2195 msg
.msg_controllen
= control
.cmsg
.cmsg_len
;
2197 if (sendmsg(fd2
, &msg
, 0) != 1) e(0);
2200 iov
.iov_len
= sizeof(buf
);
2202 memset(&msg
, 0, sizeof(msg
));
2205 msg
.msg_control
= control
.buf
;
2206 msg
.msg_controllen
= sizeof(control
);
2208 if (recvmsg(fd
, &msg
, 0) != 1) e(0);
2209 if (buf
[0] != 'C') e(0);
2211 seen_tos
= seen_ttl
= seen_pktinfo
= 0;
2212 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
!= NULL
;
2213 cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
2214 if (cmsg
->cmsg_level
!= IPPROTO_IPV6
) e(0);
2215 switch (cmsg
->cmsg_type
) {
2217 if (seen_tos
++) e(0);
2218 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(val
))) e(0);
2219 memcpy(&val
, CMSG_DATA(cmsg
), sizeof(val
));
2220 if (val
!= 94) e(0);
2223 if (seen_ttl
++) e(0);
2224 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(val
))) e(0);
2225 memcpy(&val
, CMSG_DATA(cmsg
), sizeof(val
));
2226 if (val
!= 39) e(0);
2229 if (seen_pktinfo
++) e(0);
2230 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(ipi6
))) e(0);
2231 memcpy(&ipi6
, CMSG_DATA(cmsg
), sizeof(ipi6
));
2232 if (memcmp(&ipi6
.ipi6_addr
, &in6addr_loopback
,
2233 sizeof(ipi6
.ipi6_addr
))) e(0);
2234 if (ipi6
.ipi6_ifindex
!= ifindex
) e(0);
2240 if (!seen_tos
) e(0);
2241 if (!seen_ttl
) e(0);
2242 if (!seen_pktinfo
) e(0);
2245 * Test that (for IPv6) an option of -1 overrides setsockopt.
2246 * Also test that we can provide all supported IPv6 options at once.
2249 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &val
,
2250 sizeof(val
)) != 0) e(0);
2255 memset(&msg
, 0, sizeof(msg
));
2256 msg
.msg_control
= control
.buf
;
2257 msg
.msg_controllen
= sizeof(control
.buf
);
2260 control
.cmsg
.cmsg_len
= CMSG_LEN(sizeof(val
));
2261 control
.cmsg
.cmsg_level
= IPPROTO_IPV6
;
2262 control
.cmsg
.cmsg_type
= IPV6_TCLASS
;
2263 memcpy(CMSG_DATA(&control
.cmsg
), &val
, sizeof(val
));
2265 size
= CMSG_SPACE(sizeof(val
));
2267 if ((cmsg
= CMSG_NXTHDR(&msg
, &control
.cmsg
)) == NULL
) e(0);
2269 cmsg2
.cmsg_len
= CMSG_LEN(sizeof(val
));
2270 cmsg2
.cmsg_level
= IPPROTO_IPV6
;
2271 cmsg2
.cmsg_type
= IPV6_HOPLIMIT
;
2272 memcpy(cmsg
, &cmsg2
, sizeof(cmsg2
));
2273 memcpy(CMSG_DATA(cmsg
), &val
, sizeof(val
));
2275 size
+= CMSG_SPACE(sizeof(val
));
2277 if ((cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) == NULL
) e(0);
2278 cmsg2
.cmsg_len
= CMSG_LEN(sizeof(ipi6
));
2279 cmsg2
.cmsg_level
= IPPROTO_IPV6
;
2280 cmsg2
.cmsg_type
= IPV6_PKTINFO
;
2281 memcpy(cmsg
, &cmsg2
, sizeof(cmsg2
));
2282 memset(&ipi6
, 0, sizeof(ipi6
));
2283 memcpy(CMSG_DATA(cmsg
), &ipi6
, sizeof(ipi6
));
2285 size
+= CMSG_SPACE(sizeof(ipi6
));
2287 if (size
> sizeof(control
.buf
)) e(0);
2289 memset(&msg
, 0, sizeof(msg
));
2290 msg
.msg_name
= (struct sockaddr
*)&sin6
;
2291 msg
.msg_namelen
= sizeof(sin6
);
2294 msg
.msg_control
= control
.buf
;
2295 msg
.msg_controllen
= size
;
2297 if (sendmsg(fd2
, &msg
, 0) != 1) e(0);
2300 iov
.iov_len
= sizeof(buf
);
2302 memset(&msg
, 0, sizeof(msg
));
2305 msg
.msg_control
= control
.buf
;
2306 msg
.msg_controllen
= sizeof(control
);
2308 if (recvmsg(fd
, &msg
, 0) != 1) e(0);
2309 if (buf
[0] != 'D') e(0);
2311 seen_tos
= seen_ttl
= 0;
2312 for (cmsg
= CMSG_FIRSTHDR(&msg
); cmsg
!= NULL
;
2313 cmsg
= CMSG_NXTHDR(&msg
, cmsg
)) {
2314 if (cmsg
->cmsg_level
!= IPPROTO_IPV6
) e(0);
2315 switch (cmsg
->cmsg_type
) {
2317 if (seen_tos
++) e(0);
2318 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(val
))) e(0);
2319 memcpy(&val
, CMSG_DATA(cmsg
), sizeof(val
));
2323 if (seen_ttl
++) e(0);
2324 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(val
))) e(0);
2325 memcpy(&val
, CMSG_DATA(cmsg
), sizeof(val
));
2326 if (val
!= 78) e(0);
2332 if (!seen_tos
) e(0);
2333 if (!seen_ttl
) e(0);
2335 if (close(fd2
) != 0) e(0);
2336 if (close(fd
) != 0) e(0);
2340 * Test receiving IPv4 packets on IPv6 sockets.
2345 struct sockaddr_in6 sin6
;
2346 struct sockaddr_in sin
;
2349 struct cmsghdr
*cmsg
;
2350 struct in6_pktinfo ipi6
;
2351 unsigned int ifindex
;
2352 char buf
[1], buf2
[256];
2357 ifindex
= if_nametoindex(LOOPBACK_IFNAME
);
2358 if (ifindex
== 0) e(0);
2360 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
2363 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
2367 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &val
,
2368 sizeof(val
)) != 0) e(0);
2370 memset(&sin6
, 0, sizeof(sin6
));
2371 sin6
.sin6_family
= AF_INET6
;
2372 sin6
.sin6_port
= htons(TEST_PORT_A
);
2374 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
2376 if ((fd2
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
2378 memset(&sin
, 0, sizeof(sin
));
2379 sin
.sin_family
= AF_INET
;
2380 sin
.sin_port
= htons(TEST_PORT_A
);
2381 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
2383 if (sendto(fd2
, "A", 1, 0, (struct sockaddr
*)&sin
, sizeof(sin
)) != 1)
2387 iov
.iov_len
= sizeof(buf
);
2389 memset(&msg
, 0, sizeof(msg
));
2390 msg
.msg_name
= (struct sockaddr
*)&sin6
;
2391 msg
.msg_namelen
= sizeof(sin6
);
2394 msg
.msg_control
= buf2
;
2395 msg
.msg_controllen
= sizeof(buf2
);
2397 if (recvmsg(fd
, &msg
, 0) != 1) e(0);
2398 if (buf
[0] != 'A') e(0);
2400 if (msg
.msg_namelen
!= sizeof(sin6
)) e(0);
2401 if (sin6
.sin6_family
!= AF_INET6
) e(0);
2402 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
2403 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
2406 if ((cmsg
= CMSG_FIRSTHDR(&msg
)) == NULL
) e(0);
2407 if (cmsg
->cmsg_level
!= IPPROTO_IPV6
) e(0);
2408 if (cmsg
->cmsg_type
!= IPV6_PKTINFO
) e(0);
2409 if (cmsg
->cmsg_len
!= CMSG_LEN(sizeof(ipi6
))) e(0);
2412 * The packet was sent from loopback to loopback, both with IPv4-mapped
2413 * IPv6 addresses, so we can simply compare source and destination.
2415 memcpy(&ipi6
, CMSG_DATA(cmsg
), sizeof(ipi6
));
2416 if (memcmp(&sin6
.sin6_addr
, &ipi6
.ipi6_addr
, sizeof(sin6
.sin6_addr
)))
2418 if (ipi6
.ipi6_ifindex
!= ifindex
) e(0);
2420 if (CMSG_NXTHDR(&msg
, cmsg
) != NULL
) e(0);
2423 * Sqeeze in a quick test to see what happens if the receiver end does
2424 * not provide a control buffer after having requested control data,
2425 * because a half-complete version of this test triggered a bug there..
2427 if (sendto(fd2
, "B", 1, 0, (struct sockaddr
*)&sin
, sizeof(sin
)) != 1)
2430 if (recvfrom(fd
, buf
, sizeof(buf
), 0, NULL
, NULL
) != 1) e(0);
2431 if (buf
[0] != 'B') e(0);
2433 if (close(fd2
) != 0) e(0);
2434 if (close(fd
) != 0) e(0);
2438 * Test that binding a socket of the given type to a privileged port is
2444 struct sockaddr_in sin
;
2445 struct sockaddr_in6 sin6
;
2448 if ((fd
= socket(AF_INET
, type
, 0)) < 0) e(0);
2450 memset(&sin
, 0, sizeof(sin
));
2451 sin
.sin_family
= AF_INET
;
2452 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
2454 for (port
= IPPORT_RESERVED
- 1; port
>= 0; port
--) {
2455 sin
.sin_port
= htons(port
);
2457 if (bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != -1) e(0);
2458 if (errno
== EADDRINUSE
) continue;
2459 if (errno
!= EACCES
) e(0);
2463 for (port
= IPPORT_RESERVED
; port
<= UINT16_MAX
; port
++) {
2464 sin
.sin_port
= htons(port
);
2466 if (bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) == 0)
2468 if (errno
!= EADDRINUSE
) e(0);
2471 if (close(fd
) != 0) e(0);
2473 if ((fd
= socket(AF_INET6
, type
, 0)) < 0) e(0);
2475 memset(&sin6
, 0, sizeof(sin6
));
2476 sin6
.sin6_family
= AF_INET6
;
2477 memcpy(&sin6
.sin6_addr
, &in6addr_loopback
, sizeof(sin6
.sin6_addr
));
2479 for (port
= IPV6PORT_RESERVED
- 1; port
>= 0; port
--) {
2480 sin6
.sin6_port
= htons(port
);
2482 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1)
2484 if (errno
== EADDRINUSE
) continue;
2485 if (errno
!= EACCES
) e(0);
2489 for (port
= IPV6PORT_RESERVED
; port
<= UINT16_MAX
; port
++) {
2490 sin6
.sin6_port
= htons(port
);
2492 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) == 0)
2494 if (errno
!= EADDRINUSE
) e(0);
2497 if (close(fd
) != 0) e(0);
2501 * Test that binding to privileged ports is disallowed for non-root users.
2502 * Also make sure that such users cannot create raw sockets at all. This test
2503 * is not to be run by root, but for convenience we first try to drop
2504 * privileges for the duration of the test anyway.
2515 sub91i(SOCK_STREAM
);
2519 for (i
= 0; i
< IPPROTO_MAX
; i
++) {
2520 if (socket(AF_INET
, SOCK_RAW
, i
) != -1) e(0);
2521 if (errno
!= EACCES
) e(0);
2522 if (socket(AF_INET6
, SOCK_RAW
, i
) != -1) e(0);
2523 if (errno
!= EACCES
) e(0);
2530 * Test setting and getting basic UDP/RAW multicast transmission options.
2538 socklib_multicast_tx_options(SOCK_DGRAM
);
2542 * Test TCP socket state changes related to the listen queue. This test is
2543 * derived from test90y, but sufficiently different to be its own copy.
2548 struct sockaddr_in6 sin6A
, sin6B
, sin6C
;
2554 int fd
, fd2
, fd3
, fd4
, val
, fl
;
2558 if ((fd
= socket(AF_INET6
, SOCK_STREAM
| SOCK_NONBLOCK
, 0)) < 0) e(0);
2561 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &val
, sizeof(val
)) != 0)
2564 memset(&sin6A
, 0, sizeof(sin6A
));
2565 sin6A
.sin6_family
= AF_INET6
;
2566 sin6A
.sin6_port
= htons(TEST_PORT_A
);
2567 memcpy(&sin6A
.sin6_addr
, &in6addr_loopback
, sizeof(sin6A
.sin6_addr
));
2569 if (bind(fd
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2572 * Any socket options should be inherited from the listening socket at
2573 * connect time, and not be re-inherited at accept time, to the extent
2574 * that they are inherited at all. TCP/IP level options are not.
2577 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDLOWAT
, &val
, sizeof(val
)) != 0)
2580 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &val
, sizeof(val
)) != 0)
2583 if (listen(fd
, 5) != 0) e(0);
2585 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2587 memset(&sin6B
, 0, sizeof(sin6B
));
2588 sin6B
.sin6_family
= AF_INET6
;
2589 sin6B
.sin6_port
= htons(0);
2590 memcpy(&sin6B
.sin6_addr
, &in6addr_loopback
, sizeof(sin6B
.sin6_addr
));
2593 if (setsockopt(fd2
, IPPROTO_TCP
, TCP_NODELAY
, &val
, sizeof(val
)) != 0)
2596 if (bind(fd2
, (struct sockaddr
*)&sin6B
, sizeof(sin6B
)) != 0) e(0);
2598 len
= sizeof(sin6B
);
2599 if (getsockname(fd2
, (struct sockaddr
*)&sin6B
, &len
) != 0) e(0);
2600 if (len
!= sizeof(sin6B
)) e(0);
2601 if (sin6B
.sin6_port
== htons(0)) e(0);
2603 if (connect(fd2
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2606 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDLOWAT
, &val
, sizeof(val
)) != 0)
2609 if (setsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &val
, sizeof(val
)) != 0)
2613 * Obtaining the peer name should work. As always, the name should be
2614 * inherited from the listening socket.
2616 len
= sizeof(sin6C
);
2617 if (getpeername(fd2
, (struct sockaddr
*)&sin6C
, &len
) != 0) e(0);
2618 if (sin6C
.sin6_len
!= sizeof(sin6C
)) e(0);
2619 if (sin6C
.sin6_family
!= AF_INET6
) e(0);
2620 if (sin6C
.sin6_port
!= htons(TEST_PORT_A
)) e(0);
2621 if (memcmp(&sin6C
.sin6_addr
, &in6addr_loopback
,
2622 sizeof(sin6C
.sin6_addr
)) != 0) e(0);
2625 * Sending to the socket should work, and it should be possible to
2626 * receive the data from the other side once accepted.
2628 if (send(fd2
, "Hello, ", 7, 0) != 7) e(0);
2629 if (send(fd2
, "world!", 6, 0) != 6) e(0);
2631 /* Shutdown settings should be visible after accepting, too. */
2632 if (shutdown(fd2
, SHUT_RDWR
) != 0) e(0);
2634 memset(&sin6C
, 0, sizeof(sin6C
));
2635 len
= sizeof(sin6C
);
2636 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin6C
, &len
)) < 0) e(0);
2637 if (sin6C
.sin6_len
!= sizeof(sin6C
)) e(0);
2638 if (sin6C
.sin6_family
!= AF_INET6
) e(0);
2639 if (sin6C
.sin6_port
!= sin6B
.sin6_port
) e(0);
2640 if (memcmp(&sin6C
.sin6_addr
, &in6addr_loopback
,
2641 sizeof(sin6C
.sin6_addr
)) != 0) e(0);
2644 if (getsockopt(fd3
, SOL_SOCKET
, SO_SNDLOWAT
, &val
, &len
) != 0) e(0);
2645 if (len
!= sizeof(val
)) e(0);
2646 if (val
!= 123) e(0);
2649 if (getsockopt(fd3
, SOL_SOCKET
, SO_RCVBUF
, &val
, &len
) != 0) e(0);
2650 if (len
!= sizeof(val
)) e(0);
2651 if (val
!= 32768) e(0);
2653 if ((fl
= fcntl(fd3
, F_GETFL
)) == -1) e(0);
2654 if (!(fl
& O_NONBLOCK
)) e(0);
2655 if (fcntl(fd3
, F_SETFL
, fl
& ~O_NONBLOCK
) != 0) e(0);
2657 if (recv(fd3
, buf
, 7, 0) != 7) e(0);
2658 if (memcmp(buf
, "Hello, ", 7) != 0) e(0);
2659 if (recv(fd3
, buf
, 7, 0) != 6) e(0);
2660 if (memcmp(buf
, "world!", 6) != 0) e(0);
2662 if (recv(fd3
, buf
, sizeof(buf
), 0) != 0) e(0);
2665 * Unlike in the UDS test, the other side's shutdown-for-reading is not
2666 * visible to this side, so sending data should work just fine until we
2667 * close or shut down the socket ourselves. The other side will simply
2668 * discard the incoming data.
2670 if (send(fd3
, "", 1, MSG_NOSIGNAL
) != 1) e(0);
2672 if (close(fd2
) != 0) e(0);
2673 if (close(fd3
) != 0) e(0);
2676 * If the connection pending acceptance is closed, the connection must
2677 * remain on the queue, and the accepting party will read EOF from it.
2678 * Try once without pending data, once with pending data.
2680 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2682 if (connect(fd2
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2684 if (close(fd2
) != 0) e(0);
2686 len
= sizeof(sin6B
);
2687 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin6B
, &len
)) < 0) e(0);
2690 if (getsockopt(fd3
, SOL_SOCKET
, SO_SNDLOWAT
, &val
, &len
) != 0) e(0);
2691 if (len
!= sizeof(val
)) e(0);
2692 if (val
!= 456) e(0);
2695 if (getsockopt(fd3
, SOL_SOCKET
, SO_RCVBUF
, &val
, &len
) != 0) e(0);
2696 if (len
!= sizeof(val
)) e(0);
2697 if (val
!= 16384) e(0);
2699 if (recv(fd3
, buf
, sizeof(buf
), 0) != 0) e(0);
2701 if (close(fd3
) != 0) e(0);
2703 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2705 if (connect(fd2
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2707 if (send(fd2
, "Hello!", 6, 0) != 6) e(0);
2708 if (close(fd2
) != 0) e(0);
2710 len
= sizeof(sin6B
);
2711 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin6B
, &len
)) < 0) e(0);
2713 if (recv(fd3
, buf
, sizeof(buf
), 0) != 6) e(0);
2714 if (memcmp(buf
, "Hello!", 6) != 0) e(0);
2716 if (recv(fd3
, buf
, sizeof(buf
), 0) != 0) e(0);
2718 if (close(fd3
) != 0) e(0);
2721 * If the connection pending acceptance is aborted, the listening
2722 * socket should pretend as though the connection was never there.
2724 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2726 if (connect(fd2
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2732 if (select(fd
+ 1, &fds
, NULL
, NULL
, &tv
) != 1) e(0);
2733 if (!FD_ISSET(fd
, &fds
)) e(0);
2735 memset(&l
, 0, sizeof(l
));
2738 if (setsockopt(fd2
, SOL_SOCKET
, SO_LINGER
, &l
, sizeof(l
)) != 0) e(0);
2740 if (close(fd2
) != 0) e(0);
2742 if (select(fd
+ 1, &fds
, NULL
, NULL
, &tv
) != 0) e(0);
2743 if (FD_ISSET(fd
, &fds
)) e(0);
2745 len
= sizeof(sin6B
);
2746 if (accept(fd
, (struct sockaddr
*)&sin6B
, &len
) != -1) e(0);
2747 if (errno
!= EWOULDBLOCK
) e(0);
2750 * Try the same thing, but now with the connection sandwiched between
2751 * two different pending connections, which should be left intact.
2753 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2755 if (connect(fd2
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2757 if (send(fd2
, "A", 1, 0) != 1) e(0);
2759 if ((fd3
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2761 if (connect(fd3
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2763 if (send(fd3
, "B", 1, 0) != 1) e(0);
2765 if ((fd4
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2767 if (connect(fd4
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2769 if (send(fd4
, "C", 1, 0) != 1) e(0);
2771 if (setsockopt(fd3
, SOL_SOCKET
, SO_LINGER
, &l
, sizeof(l
)) != 0) e(0);
2773 if (close(fd3
) != 0) e(0);
2775 len
= sizeof(sin6B
);
2776 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin6B
, &len
)) < 0) e(0);
2778 if (recv(fd3
, buf
, sizeof(buf
), 0) != 1) e(0);
2779 if (buf
[0] != 'A') e(0);
2781 if (close(fd3
) != 0) e(0);
2782 if (close(fd2
) != 0) e(0);
2788 if (select(fd
+ 1, &fds
, NULL
, NULL
, &tv
) != 1) e(0);
2789 if (!FD_ISSET(fd
, &fds
)) e(0);
2791 len
= sizeof(sin6B
);
2792 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin6B
, &len
)) < 0) e(0);
2794 if (recv(fd3
, buf
, sizeof(buf
), 0) != 1) e(0);
2795 if (buf
[0] != 'C') e(0);
2797 if (close(fd3
) != 0) e(0);
2798 if (close(fd4
) != 0) e(0);
2800 if (select(fd
+ 1, &fds
, NULL
, NULL
, &tv
) != 0) e(0);
2801 if (FD_ISSET(fd
, &fds
)) e(0);
2803 len
= sizeof(sin6B
);
2804 if (accept(fd
, (struct sockaddr
*)&sin6B
, &len
) != -1) e(0);
2805 if (errno
!= EWOULDBLOCK
) e(0);
2808 * If the listening socket was closed, the sockets pending acceptance
2811 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2813 if (connect(fd2
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2815 if ((fd3
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
2817 if (connect(fd3
, (struct sockaddr
*)&sin6A
, sizeof(sin6A
)) != 0) e(0);
2819 if (close(fd
) != 0) e(0);
2821 if (recv(fd2
, buf
, sizeof(buf
), 0) != -1) e(0);
2822 if (errno
!= ECONNRESET
) e(0);
2824 if (recv(fd2
, buf
, sizeof(buf
), 0) != 0) e(0);
2826 if (recv(fd3
, buf
, sizeof(buf
), 0) != -1) e(0);
2827 if (errno
!= ECONNRESET
) e(0);
2829 if (recv(fd3
, buf
, sizeof(buf
), 0) != 0) e(0);
2831 if (close(fd3
) != 0) e(0);
2833 if (close(fd2
) != 0) e(0);
2837 * Obtain a pair of connected TCP socket.
2840 get_tcp_pair(int domain
, int type
, int protocol
, int fd
[2])
2842 struct sockaddr_in6 sin6
;
2843 struct sockaddr_in sin
;
2844 struct sockaddr
*addr
;
2845 socklen_t addr_len
, len
;
2848 if (domain
== AF_INET6
) {
2849 memset(&sin6
, 0, sizeof(sin6
));
2850 sin6
.sin6_family
= AF_INET6
;
2851 memcpy(&sin6
.sin6_addr
, &in6addr_loopback
,
2852 sizeof(sin6
.sin6_addr
));
2854 addr
= (struct sockaddr
*)&sin6
;
2855 addr_len
= sizeof(sin6
);
2857 assert(domain
== AF_INET
);
2859 memset(&sin
, 0, sizeof(sin
));
2860 sin
.sin_family
= AF_INET
;
2861 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
2863 addr
= (struct sockaddr
*)&sin
;
2864 addr_len
= sizeof(sin
);
2867 if ((lfd
= socket(domain
, type
, protocol
)) < 0) e(0);
2869 if (bind(lfd
, addr
, addr_len
) != 0) e(0);
2872 if (getsockname(lfd
, addr
, &len
) != 0) e(0);
2873 if (len
!= addr_len
) e(0);
2875 if (listen(lfd
, 1) != 0) e(0);
2877 if ((fd
[0] = socket(domain
, type
, protocol
)) < 0) e(0);
2880 if (setsockopt(fd
[0], IPPROTO_TCP
, TCP_NODELAY
, &val
,
2881 sizeof(val
)) != 0) e(0);
2883 if (connect(fd
[0], addr
, addr_len
) != 0) e(0);
2886 if ((fd
[1] = accept(lfd
, addr
, &len
)) < 0) e(0);
2887 if (len
!= addr_len
) e(0);
2889 if (setsockopt(fd
[1], IPPROTO_TCP
, TCP_NODELAY
, &val
,
2890 sizeof(val
)) != 0) e(0);
2892 if (close(lfd
) != 0) e(0);
2898 * Test large transfers and MSG_WAITALL.
2907 get_tcp_pair(AF_INET6
, SOCK_STREAM
, 0, fd
);
2909 socklib_large_transfers(fd
);
2911 get_tcp_pair(AF_INET
, SOCK_STREAM
, 0, fd
);
2913 socklib_large_transfers(fd
);
2917 * A randomized producer-consumer test for stream sockets. As part of this,
2918 * we also perform very basic bulk functionality tests of FIONREAD, MSG_PEEK,
2919 * MSG_DONTWAIT, and MSG_WAITALL.
2928 get_tcp_pair(AF_INET6
, SOCK_STREAM
, 0, fd
);
2930 socklib_producer_consumer(fd
);
2932 get_tcp_pair(AF_INET
, SOCK_STREAM
, 0, fd
);
2934 socklib_producer_consumer(fd
);
2938 * Cause a receive call on the peer side of the connection of 'fd' to be
2939 * aborted in a protocol-specific way. Return -1 to indicate that the given
2940 * file descriptor has been closed.
2943 test91_reset(int fd
, const char * data __unused
, size_t len __unused
)
2949 if (setsockopt(fd
, SOL_SOCKET
, SO_LINGER
, &l
, sizeof(l
)) != 0) e(0);
2951 if (close(fd
) != 0) e(0);
2957 * Test for receiving on stream sockets. In particular, test SO_RCVLOWAT,
2958 * MSG_PEEK, MSG_DONTWAIT, and MSG_WAITALL.
2966 socklib_stream_recv(get_tcp_pair
, AF_INET
, SOCK_STREAM
,
2971 * Return the send and receive buffer sizes for sockets of the given type. The
2972 * two individual values are stored in 'sndbuf' and 'rcvbuf', for each that is
2973 * not NULL, and the sum is returned from the call.
2976 get_buf_sizes(int type
, int * sndbufp
, int * rcvbufp
)
2979 int fd
, sndbuf
, rcvbuf
;
2981 if ((fd
= socket(AF_INET
, type
, 0)) < 0) e(0);
2983 len
= sizeof(sndbuf
);
2984 if (getsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &sndbuf
, &len
) != 0) e(0);
2985 if (len
!= sizeof(sndbuf
)) e(0);
2986 if (sndbufp
!= NULL
)
2989 len
= sizeof(rcvbuf
);
2990 if (getsockopt(fd
, SOL_SOCKET
, SO_RCVBUF
, &rcvbuf
, &len
) != 0) e(0);
2991 if (len
!= sizeof(rcvbuf
)) e(0);
2992 if (rcvbufp
!= NULL
)
2995 if (close(fd
) != 0) e(0);
2997 return sndbuf
+ rcvbuf
;
3001 * The following constant should be set to the window size used within lwIP.
3002 * There is currently no way to obtain this constant from the LWIP service, nor
3003 * would that be information that should ever be used by general applications,
3004 * but we need it to fill socket receive queues in a reliable way. TODO: find
3005 * a better solution for this general problem.
3007 #define WINDOW_SIZE 16384 /* TCP_WND in lwipopt.h, keep in sync! */
3009 #define CHUNK 4096 /* base I/O chunk size */
3010 #define USLEEP_TIME 250000 /* increase on wimpy platforms if needed */
3013 * Fill the receive of socket 'rfd' with data, and if 'fill_send' is non-zero,
3014 * also the send queue of socket 'sfd'. If 'fill_send' is zero, 'delta' may be
3015 * a non-zero value indicating how many bytes extra (delta > 0) or fewer
3016 * (delta < 0) should be sent compared to the receive queue size.
3019 fill_tcp_bufs(int sfd
, int rfd
, int fill_send
, int delta
)
3021 unsigned char buf
[CHUNK
], c
;
3023 int sndbuf
, rcvbuf
, mss
, chunk
, left
, res
;
3025 assert(!fill_send
|| delta
== 0);
3027 (void)get_buf_sizes(SOCK_STREAM
, &sndbuf
, &rcvbuf
);
3030 if (getsockopt(sfd
, IPPROTO_TCP
, TCP_MAXSEG
, &mss
, &len
) != 0) e(0);
3036 memset(buf
, 0, sizeof(buf
));
3039 * In general, TCP is not designed for what we want to do here, which
3040 * is to control the contents of the receive buffer down to the last
3041 * byte. We already assume that the caller has disabled the Nagle
3042 * algorithm, but we still have to deal with other algorithms that
3043 * effectively get in the way of full control of the receive buffer.
3045 * In particular, we have to work around an issue where lwIP decides to
3046 * start shrinking the window earlier than necessary. This issue
3047 * triggers during the transition from a fully open window to a reduced
3048 * window. If no acknowledgement is sent when exactly that point is
3049 * reached, the next acknowlegment will not announce the full size of
3050 * the remainder of the window. This appears to be part of the silly
3051 * window avoidance logic, so it is probably intentional behavior and
3052 * thus we have to work around it.
3054 * So far it appears that filling up just the window size does the job,
3055 * as long as the last segment is a full MSS-sized segment and each
3056 * segment is acknowledged (which is why we send data in the other
3057 * direction). Anything short of that may trigger edge cases that, in
3058 * some cases, show up only on slow platforms (e.g. BeagleBones).
3060 * Note that while test91z also fills up receive queues using its own
3061 * algorithm, it sets the receive queue to the window size, thereby
3062 * avoiding the need for this more complicated algorithm.
3064 for (left
= rcvbuf
- WINDOW_SIZE
; left
> 0; left
-= chunk
) {
3065 chunk
= (left
% mss
!= 0) ? (left
% mss
) : mss
;
3066 assert(chunk
<= left
);
3068 if (send(sfd
, buf
, chunk
, 0) != chunk
) e(0);
3070 if (send(rfd
, ".", 1, 0) != 1) e(0);
3072 if (recv(sfd
, &c
, 1, 0) != 1) e(0);
3076 /* We are done with the hard part. Now fill up the rest. */
3080 for (left
= WINDOW_SIZE
+ delta
; left
> 0; left
-= res
) {
3081 chunk
= MIN(left
, sizeof(buf
));
3083 res
= send(sfd
, buf
, chunk
, 0);
3086 if (res
> chunk
) e(0);
3091 * Signal handler which just needs to exist, so that invoking it will interrupt
3092 * an ongoing system call.
3095 test91_got_signal(int sig __unused
)
3102 * Test for sending on stream sockets. The quick summary here is that send()
3103 * should basically act as the mirror of recv(MSG_WAITALL), i.e., it should
3104 * keep suspending until all data is sent (or the call is interrupted or no
3105 * more can possibly be sent), and, SO_SNDLOWAT, mirroring SO_RCVLOWAT, acts as
3106 * an admission test for the send: nothing is sent until there is room in the
3107 * send buffer (i.e., the peer's receive buffer) for at least the low send
3108 * watermark, or the whole send request length, whichever is smaller. In
3109 * addition, select(2) should use the same threshold.
3111 * This test is a copy of test90v, and would be in socklib instead, were it not
3112 * for the fact that TCP's segmentation and silly window avoidance make it
3113 * impossible to perform the same exact, byte-granular test. Instead, this TCP
3114 * implementation paints with a somewhat broader brush, using send and receive
3115 * chunk sizes large enough to overcome the normally desirable TCP features
3116 * that are now getting in the way. As a result, this copy of the test is not
3117 * only somewhat less effective but also a bit more reliant on specific (TCP)
3118 * settings, although the whole test is still way too useful to skip at all.
3121 sub91o(int iroom
, int istate
, int slowat
, int len
, int bits
, int act
)
3123 struct sigaction sa
;
3125 char buf
[CHUNK
* 4];
3128 int fd
[2], min
, flags
, res
, err
;
3129 int pfd
[2], orig_iroom
, eroom
, tstate
, fl
, status
;
3131 if (get_tcp_pair(AF_INET6
, SOCK_STREAM
, 0, fd
) != 0) e(0);
3134 * Set up the initial condition on the sockets.
3136 fill_tcp_bufs(fd
[0], fd
[1], 1 /*fill_send*/, 0 /*delta*/);
3139 * Receive a bit more than we send, to free up enough room (the MSS) to
3140 * get things going again.
3145 if (recv(fd
[1], buf
, iroom
, 0) != iroom
) e(0);
3149 case 1: if (shutdown(fd
[0], SHUT_WR
) != 0) e(0); break;
3150 case 2: if (close(fd
[1]) != 0) e(0); break;
3153 if (setsockopt(fd
[0], SOL_SOCKET
, SO_SNDLOWAT
, &slowat
,
3154 sizeof(slowat
)) != 0) e(0);
3156 /* SO_SNDLOWAT is always bounded by the actual send length. */
3157 min
= MIN(len
, slowat
);
3159 flags
= MSG_NOSIGNAL
;
3160 if (bits
& 1) flags
|= MSG_DONTWAIT
;
3163 * Do a quick select test to see if its result indeed matches whether
3164 * the available space in the "send" buffer meets the threshold.
3167 FD_SET(fd
[0], &fds
);
3170 res
= select(fd
[0] + 1, NULL
, &fds
, NULL
, &tv
);
3171 if (res
< 0 || res
> 1) e(0);
3172 if (res
!= (iroom
>= slowat
|| istate
> 0)) e(0);
3173 if (res
== 1 && !FD_ISSET(fd
[0], &fds
)) e(0);
3176 * Cut short a whole lot of cases, to avoid the overhead of forking,
3177 * namely when we know the call should return immediately. This is the
3178 * case when the socket state disallows further sending, or when all
3179 * data could be sent, or when the call was non-blocking. The low
3180 * send watermark only helps determine whether anything was sent here.
3182 if (istate
> 0 || iroom
>= len
|| (flags
& MSG_DONTWAIT
)) {
3183 res
= send(fd
[0], buf
, len
, flags
);
3186 if (res
!= -1) e(0);
3187 if (errno
!= EPIPE
&& errno
!= ECONNRESET
) e(0);
3188 } else if (iroom
>= len
) {
3189 if (res
!= len
) e(0);
3190 } else if (iroom
>= min
) {
3191 if (res
< orig_iroom
|| res
> iroom
) e(0);
3193 if (res
!= -1) e(0);
3194 if (errno
!= EWOULDBLOCK
) e(0);
3197 /* Early cleanup and return to avoid even more code clutter. */
3198 if (istate
!= 2 && close(fd
[1]) != 0) e(0);
3199 if (close(fd
[0]) != 0) e(0);
3205 * Now starts the interesting stuff: the send call should now block,
3206 * even though if we add MSG_DONTWAIT it may not return EWOULDBLOCK,
3207 * because MSG_DONTWAIT prevents the send from blocking after partial
3208 * completion. As such, we can only test our expectations by letting
3209 * the call block, in a child process, and waiting. We do test as much
3210 * of the above assumption as we can for safety right here, but this is
3211 * not a substitute for actually blocking even in these cases!
3214 if (send(fd
[0], buf
, len
, flags
| MSG_DONTWAIT
) != -1) e(0);
3215 if (errno
!= EWOULDBLOCK
) e(0);
3219 * If (act < 9), we receive 0, 1, or 2 bytes from the receive queue
3220 * before forcing the send call to terminate in one of three ways.
3222 * If (act == 9), we use a signal to interrupt the send call.
3225 eroom
= (act
% 3) * (CHUNK
+ CHUNK
/ 2 - 1);
3230 if (pipe2(pfd
, O_NONBLOCK
) != 0) e(0);
3237 if (close(fd
[1]) != 0) e(0);
3238 if (close(pfd
[0]) != 0) e(0);
3241 memset(&sa
, 0, sizeof(sa
));
3242 sa
.sa_handler
= test91_got_signal
;
3243 if (sigaction(SIGUSR1
, &sa
, NULL
) != 0) e(0);
3246 res
= send(fd
[0], buf
, len
, flags
);
3249 if (write(pfd
[1], &res
, sizeof(res
)) != sizeof(res
)) e(0);
3250 if (write(pfd
[1], &err
, sizeof(err
)) != sizeof(err
)) e(0);
3257 if (close(pfd
[1]) != 0) e(0);
3260 * Allow the child to enter the blocking send(2), and check the pipe
3261 * to see if it is really blocked.
3263 if (usleep(USLEEP_TIME
) != 0) e(0);
3265 if (read(pfd
[0], &res
, sizeof(res
)) != -1) e(0);
3266 if (errno
!= EAGAIN
) e(0);
3269 if (recv(fd
[1], buf
, eroom
, 0) != eroom
) e(0);
3272 * The threshold for the send is now met if the entire request
3273 * has been satisfied.
3275 if (iroom
+ eroom
>= len
) {
3276 if ((fl
= fcntl(pfd
[0], F_GETFL
, 0)) == -1) e(0);
3277 if (fcntl(pfd
[0], F_SETFL
, fl
& ~O_NONBLOCK
) != 0)
3280 if (read(pfd
[0], &res
, sizeof(res
)) != sizeof(res
))
3282 if (read(pfd
[0], &err
, sizeof(err
)) != sizeof(err
))
3285 if (res
!= len
) e(0);
3294 * Now test various ways to terminate the send call.
3296 * For other socket drivers, there should also be a case where
3297 * a socket error is raised instead. For UDS there is no way
3298 * to do that on stream-type sockets, not even with SO_LINGER.
3301 case 0: if (shutdown(fd
[0], SHUT_WR
) != 0) e(0); break;
3302 case 1: if (close(fd
[1]) != 0) e(0); fd
[1] = -1; break;
3303 case 2: fd
[1] = test91_reset(fd
[1], NULL
, 0); break;
3306 if (kill(pid
, SIGUSR1
) != 0) e(0);
3308 if ((fl
= fcntl(pfd
[0], F_GETFL
, 0)) == -1) e(0);
3309 if (fcntl(pfd
[0], F_SETFL
, fl
& ~O_NONBLOCK
) != 0) e(0);
3311 if (read(pfd
[0], &res
, sizeof(res
)) != sizeof(res
)) e(0);
3312 if (read(pfd
[0], &err
, sizeof(err
)) != sizeof(err
)) e(0);
3315 * If the send met the threshold before being terminate or interrupted,
3316 * we should at least have sent something. Otherwise, the send was
3317 * never admitted and should return EPIPE or ECONNRESET (if the send
3318 * was terminated) or EINTR (if the child was killed).
3320 if (iroom
+ eroom
>= min
) {
3321 if (res
< MIN(orig_iroom
, len
)) e(0);
3322 if (res
> MIN(iroom
+ eroom
, len
)) e(0);
3324 if (res
!= -1) e(0);
3326 if (err
!= EPIPE
&& err
!= ECONNRESET
) e(0);
3328 if (err
!= EINTR
) e(0);
3332 if (close(pfd
[0]) != 0) e(0);
3334 if (wait(&status
) != pid
) e(0);
3335 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) e(0);
3337 if (fd
[1] != -1 && close(fd
[1]) != 0) e(0);
3338 if (close(fd
[0]) != 0) e(0);
3342 * Test for sending on stream sockets. In particular, test SO_SNDLOWAT and
3348 int iroom
, istate
, slowat
, len
, bits
, act
;
3353 for (iroom
= 0; iroom
<= CHUNK
* 2; iroom
+= CHUNK
)
3354 for (istate
= 0; istate
<= 2; istate
++)
3355 for (slowat
= CHUNK
; slowat
<= CHUNK
* 2;
3357 for (len
= CHUNK
; len
<= CHUNK
* 2;
3359 for (bits
= 0; bits
< 2; bits
++)
3360 for (act
= 0; act
<= 9; act
++)
3361 sub91o(iroom
, istate
,
3367 * Test filling up the TCP receive queue. In particular, verify that one bug I
3368 * ran into (lwIP bug #49128) is resolved.
3380 if (get_tcp_pair(AF_INET
, SOCK_STREAM
, 0, fd
) != 0) e(0);
3383 * Fill up the sockets' queues.
3385 total
= get_buf_sizes(SOCK_STREAM
, NULL
, NULL
);
3387 fill_tcp_bufs(fd
[0], fd
[1], 1 /*fill_send*/, 0 /*delta*/);
3390 * Wait long enough for the zero window probing to kick in, which used
3391 * to cause an ACK storm livelock (lwIP bug #49128).
3396 * Actually sleep a bit longer, so that the polling timer kicks in and
3397 * at least attempts to send more. This is merely an attempt to
3398 * exercise some of the polling code, and should not have any actual
3399 * effect on the rest of the test.
3404 * Make sure all the data still arrives.
3406 for (left
= total
; left
> 0; left
-= res
) {
3407 res
= recv(fd
[1], buf
, sizeof(buf
), 0);
3409 if (res
> left
) e(0);
3412 if (recv(fd
[1], buf
, sizeof(buf
), MSG_DONTWAIT
) != -1) e(0);
3413 if (errno
!= EWOULDBLOCK
) e(0);
3416 * Attempt to shut down the socket for writing after filling up the
3417 * send queue. The TCP FIN should then arrive after all the data.
3419 for (left
= total
; left
> 0; left
-= res
) {
3420 res
= send(fd
[0], buf
, MIN(left
, sizeof(buf
)), 0);
3422 if (res
> left
) e(0);
3425 if (shutdown(fd
[0], SHUT_WR
) != 0) e(0);
3427 for (left
= total
; left
> 0; left
-= res
) {
3428 res
= recv(fd
[1], buf
, sizeof(buf
), 0);
3430 if (res
> left
) e(0);
3433 if (recv(fd
[1], buf
, sizeof(buf
), 0) != 0) e(0);
3435 if (send(fd
[1], "A", 1, 0) != 1) e(0);
3437 if (recv(fd
[0], buf
, sizeof(buf
), 0) != 1) e(0);
3438 if (buf
[0] != 'A') e(0);
3440 if (close(fd
[1]) != 0) e(0);
3441 if (close(fd
[0]) != 0) e(0);
3445 * Attempt to fill up a TCP send queue with small amounts of data. While it
3446 * may or may not be possible to fill up the entire send queue with small
3447 * requests, but at least trying should not cause any problems, like the one I
3448 * filed as lwIP bug #49218.
3460 if (get_tcp_pair(AF_INET6
, SOCK_STREAM
, 0, fd
) != 0) e(0);
3463 for (c
= 0; (res
= send(fd
[0], &c
, sizeof(c
), MSG_DONTWAIT
)) > 0; c
++)
3465 if (res
!= -1) e(0);
3466 if (errno
!= EWOULDBLOCK
) e(0);
3467 if (count
< CHUNK
) e(0);
3469 if (shutdown(fd
[0], SHUT_WR
) != 0) e(0);
3471 for (c2
= 0; count
> 0; count
--, c2
++) {
3472 if (recv(fd
[1], &c
, sizeof(c
), 0) != 1) e(0);
3476 if (recv(fd
[1], &c
, sizeof(c
), 0) != 0) e(0);
3478 if (close(fd
[0]) != 0) e(0);
3479 if (close(fd
[1]) != 0) e(0);
3483 * Test that SO_RCVLOWAT is limited to the size of the receive buffer.
3486 sub91r_recv(int fill_delta
, int rlowat_delta
, int exp_delta
)
3490 int fd
[2], rlowat
, rcvlen
, res
;
3492 if (get_tcp_pair(AF_INET
, SOCK_STREAM
, 0, fd
) != 0) e(0);
3495 * Fill up the socket's receive queue, possibly minus one byte.
3497 (void)get_buf_sizes(SOCK_STREAM
, NULL
, &rcvlen
);
3499 buflen
= MAX(CHUNK
, rcvlen
+ 1);
3500 if ((buf
= malloc(buflen
)) == NULL
) e(0);
3502 fill_tcp_bufs(fd
[1], fd
[0], 0 /*fill_send*/, fill_delta
);
3504 rlowat
= rcvlen
+ rlowat_delta
;
3505 if (setsockopt(fd
[0], SOL_SOCKET
, SO_RCVLOWAT
, &rlowat
,
3506 sizeof(rlowat
)) != 0) e(0);
3508 if (ioctl(fd
[0], FIONREAD
, &res
) != 0) e(0);
3509 if (res
!= rcvlen
+ fill_delta
) e(0);
3511 res
= recv(fd
[0], buf
, rcvlen
+ 1, MSG_DONTWAIT
);
3512 if (exp_delta
< 0) {
3513 if (res
!= -1) e(0);
3514 if (errno
!= EWOULDBLOCK
) e(0);
3516 if (res
!= rcvlen
- exp_delta
) e(0);
3520 if (close(fd
[0]) != 0) e(0);
3521 if (close(fd
[1]) != 0) e(0);
3525 * Test that SO_SNDLOWAT is limited to the size of the send buffer.
3528 sub91r_send(int fill
, int slowat_delta
, int exp_delta
)
3532 int fd
[2], sndlen
, slowat
, res
;
3534 if (get_tcp_pair(AF_INET6
, SOCK_STREAM
, 0, fd
) != 0) e(0);
3537 * Fill up the socket's receive queue, and possibly put one extra byte
3538 * in the other socket's send queue.
3540 (void)get_buf_sizes(SOCK_STREAM
, &sndlen
, NULL
);
3542 buflen
= MAX(CHUNK
, sndlen
+ 1);
3543 if ((buf
= malloc(buflen
)) == NULL
) e(0);
3545 memset(buf
, 0, buflen
);
3547 fill_tcp_bufs(fd
[0], fd
[1], 0 /*fill_send*/, 0 /*delta*/);
3549 slowat
= sndlen
+ slowat_delta
;
3552 memset(buf
, 0, fill
);
3554 if (send(fd
[0], buf
, fill
, 0) != fill
) e(0);
3557 if (setsockopt(fd
[0], SOL_SOCKET
, SO_SNDLOWAT
, &slowat
,
3558 sizeof(slowat
)) != 0) e(0);
3560 res
= send(fd
[0], buf
, sndlen
+ 1, MSG_DONTWAIT
);
3561 if (exp_delta
< 0) {
3562 if (res
!= -1) e(0);
3563 if (errno
!= EWOULDBLOCK
) e(0);
3565 if (res
!= sndlen
- exp_delta
) e(0);
3569 if (close(fd
[0]) != 0) e(0);
3570 if (close(fd
[1]) != 0) e(0);
3574 * Test that on stream sockets, SO_RCVLOWAT and SO_SNDLOWAT are limited to
3575 * their respective buffer sizes. This test is derived from test90w, but
3576 * merging the two into socklib would get too messy unfortunately.
3585 * With the receive buffer filled except for one byte, all data should
3586 * be retrieved unless the threshold is not met.
3588 sub91r_recv(-1, -1, 1);
3589 sub91r_recv(-1, 0, -1);
3590 sub91r_recv(-1, 1, -1);
3593 * With the receive buffer filled completely, all data should be
3594 * retrieved in all cases.
3596 sub91r_recv(0, -1, 0);
3597 sub91r_recv(0, 0, 0);
3598 sub91r_recv(0, 1, 0);
3601 * With a send buffer that contains one byte, all data should be sent
3602 * unless the threshold is not met.
3604 sub91r_send(1, -1, 1);
3605 sub91r_send(1, 0, -1);
3606 sub91r_send(1, 1, -1);
3609 * With the send buffer filled completely, all data should be sent
3612 sub91r_send(0, -1, 0);
3613 sub91r_send(0, 0, 0);
3614 sub91r_send(0, 1, 0);
3618 * Test sending and receiving with bad pointers on a TCP socket.
3621 sub91s_tcp(char * ptr
)
3625 memset(ptr
, 'X', PAGE_SIZE
);
3627 if (get_tcp_pair(AF_INET
, SOCK_STREAM
, 0, fd
) != 0) e(0);
3629 if (send(fd
[0], "A", 1, 0) != 1) e(0);
3631 if (send(fd
[0], ptr
, PAGE_SIZE
* 2, MSG_DONTWAIT
) != -1) e(0);
3632 if (errno
!= EFAULT
) e(0);
3634 if (send(fd
[0], "B", 1, 0) != 1) e(0);
3636 if (shutdown(fd
[0], SHUT_WR
) != 0) e(0);
3638 if (recv(fd
[1], &ptr
[PAGE_SIZE
- 1], PAGE_SIZE
, MSG_WAITALL
) != -1)
3640 if (errno
!= EFAULT
) e(0);
3642 if (recv(fd
[1], ptr
, 3, MSG_DONTWAIT
) != 2) e(0);
3643 if (ptr
[0] != 'A') e(0);
3644 if (ptr
[1] != 'B') e(0);
3646 if (close(fd
[0]) != 0) e(0);
3647 if (close(fd
[1]) != 0) e(0);
3651 * Test sending and receiving with bad pointers on a UDP socket.
3654 sub91s_udp(char * ptr
)
3656 struct sockaddr_in6 sin6
;
3659 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
3661 memset(&sin6
, 0, sizeof(sin6
));
3662 sin6
.sin6_family
= AF_INET6
;
3663 sin6
.sin6_port
= htons(TEST_PORT_A
);
3664 memcpy(&sin6
.sin6_addr
, &in6addr_loopback
, sizeof(sin6
.sin6_addr
));
3666 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
3668 memset(ptr
, 'A', PAGE_SIZE
);
3670 if (sendto(fd
, &ptr
[PAGE_SIZE
/ 2], PAGE_SIZE
, 0,
3671 (struct sockaddr
*)&sin6
, sizeof(sin6
)) != -1) e(0);
3672 if (errno
!= EFAULT
) e(0);
3674 memset(ptr
, 'B', PAGE_SIZE
);
3676 if (sendto(fd
, ptr
, PAGE_SIZE
, 0, (struct sockaddr
*)&sin6
,
3677 sizeof(sin6
)) != PAGE_SIZE
) e(0);
3679 memset(ptr
, 0, PAGE_SIZE
);
3681 if (recvfrom(fd
, &ptr
[PAGE_SIZE
/ 2], PAGE_SIZE
, 0, NULL
, 0) != -1)
3683 if (errno
!= EFAULT
) e(0);
3685 if (recvfrom(fd
, ptr
, PAGE_SIZE
* 2, 0, NULL
, 0) != PAGE_SIZE
) e(0);
3686 for (i
= 0; i
< PAGE_SIZE
; i
++)
3687 if (ptr
[i
] != 'B') e(0);
3689 if (close(fd
) != 0) e(0);
3693 * Test sending and receiving with bad pointers.
3702 if ((ptr
= mmap(NULL
, PAGE_SIZE
* 2, PROT_READ
| PROT_WRITE
,
3703 MAP_ANON
| MAP_PRIVATE
, -1, 0)) == MAP_FAILED
) e(0);
3705 if (munmap(&ptr
[PAGE_SIZE
], PAGE_SIZE
) != 0) e(0);
3710 if (munmap(ptr
, PAGE_SIZE
) != 0) e(0);
3714 * Test closing TCP sockets and SO_LINGER.
3726 total
= get_buf_sizes(SOCK_STREAM
, NULL
, NULL
);
3728 memset(buf
, 0, sizeof(buf
));
3731 * Test two cases of handling connection closure:
3733 * 1) the FIN+ACK case, where the closing side finishes the close
3734 * operation once its FIN has been acknowledged;
3735 * 2) the FIN+FIN case, where the closing side finishes the close
3736 * operation once it has sent its own FIN (possibly without getting
3737 * an ACK yet) and also receives a FIN from the other side.
3739 * Since lwIP prevents us from detecting #1 without polling, which
3740 * happens twice a second, we can test #2 by shutting down the peer
3741 * connection immediately after (i=0/2) or even before (i=4/5) closing
3744 for (i
= 0; i
<= 5; i
++) {
3745 if (get_tcp_pair(AF_INET
, SOCK_STREAM
, 0, fd
) != 0) e(0);
3747 fill_tcp_bufs(fd
[0], fd
[1], 1 /*fill_send*/, 0 /*delta*/);
3749 if (close(fd
[0]) != 0) e(0);
3751 if (i
>= 4 && shutdown(fd
[1], SHUT_WR
) != 0) e(0);
3753 for (left
= total
; left
> 0; left
-= res
) {
3754 res
= recv(fd
[1], buf
, sizeof(buf
), 0);
3756 if (res
> left
) e(0);
3759 if (recv(fd
[1], buf
, sizeof(buf
), 0) != 0) e(0);
3764 * We can still send to the receiving end, but this will cause
3765 * a reset. We do this only if we have not just shut down the
3766 * writing end of this socket. Also test regular closing.
3769 if (send(fd
[1], "B", 1, 0) != 1) e(0);
3771 if (recv(fd
[1], buf
, sizeof(buf
), 0) != -1) e(0);
3772 if (errno
!= ECONNRESET
) e(0);
3775 if (close(fd
[1]) != 0) e(0);
3779 * Test that closing a socket with data still in its receive queue
3780 * causes a RST to be issued.
3782 if (get_tcp_pair(AF_INET6
, SOCK_STREAM
, 0, fd
) != 0) e(0);
3784 if (send(fd
[0], "C", 1, 0) != 1) e(0);
3786 if (recv(fd
[1], buf
, sizeof(buf
), MSG_PEEK
) != 1) e(0);
3788 if (close(fd
[1]) != 0) e(0);
3790 if (recv(fd
[0], buf
, sizeof(buf
), 0) != -1) e(0);
3791 if (errno
!= ECONNRESET
) e(0);
3793 if (close(fd
[0]) != 0) e(0);
3797 * Test closing a socket with a particular SO_LINGER setting.
3800 sub91u(int nb
, int mode
, int intr
, int onoff
, int linger
)
3803 struct timeval tv1
, tv2
;
3806 int fd
[2], pfd
[2], fl
, val
, res
, status
;
3808 get_tcp_pair((mode
& 1) ? AF_INET6
: AF_INET
, SOCK_STREAM
, 0, fd
);
3811 * Set up the socket pair.
3813 fill_tcp_bufs(fd
[0], fd
[1], 0 /*fill_send*/, 1 /*delta*/);
3815 if (mode
== 3 && shutdown(fd
[1], SHUT_WR
) != 0) e(0);
3818 l
.l_linger
= (linger
) ? (2 + intr
) : 0;
3819 if (setsockopt(fd
[0], SOL_SOCKET
, SO_LINGER
, &l
, sizeof(l
)) != 0) e(0);
3822 if ((fl
= fcntl(fd
[0], F_GETFL
)) == -1) e(0);
3823 if (fcntl(fd
[0], F_SETFL
, fl
| O_NONBLOCK
) != 0) e(0);
3826 /* We need two-way parent-child communication for this test. */
3827 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, pfd
) != 0) e(0);
3834 if (close(pfd
[1]) != 0) e(0);
3836 if (close(fd
[1]) != 0) e(0);
3838 signal(SIGUSR1
, test91_got_signal
);
3841 * Do not start closing the file descriptor until after the
3842 * parent has closed its copy.
3844 if (read(pfd
[0], &val
, sizeof(val
)) != sizeof(val
)) e(0);
3847 if (gettimeofday(&tv1
, NULL
) != 0) e(0);
3849 /* Perform the possibly blocking close(2) call. */
3851 if (close(fd
[0]) != -1) e(0);
3852 if (errno
!= EINPROGRESS
) e(0);
3854 if (close(fd
[0]) != 0) e(0);
3856 if (gettimeofday(&tv2
, NULL
) != 0) e(0);
3858 timersub(&tv2
, &tv1
, &tv1
);
3860 /* Polling may take 500ms. */
3861 val
= tv1
.tv_sec
+ ((tv1
.tv_usec
> 750000) ? 1 : 0);
3863 if (val
< 0 || val
> 2) e(0);
3865 /* Tell the parent how long the close(2) took, in seconds. */
3866 if (write(pfd
[0], &val
, sizeof(val
)) != sizeof(val
)) e(0);
3873 /* Close file descriptors here and then let the child run. */
3874 if (close(pfd
[0]) != 0) e(0);
3876 if (close(fd
[0]) != 0) e(0);
3879 if (write(pfd
[1], &val
, sizeof(val
)) != sizeof(val
)) e(0);
3882 * Wait one second until we try to close the connection ourselves, if
3883 * applicable. If we are killing the child, we add yet another second
3884 * to tell the difference between a clean close and a timeout/reset.
3889 if (kill(pid
, SIGUSR1
) != 0) e(0);
3895 * Trigger various ways in which the connection is closed, or not, in
3896 * which case the linger timeout should cause a reset.
3899 case 0: /* do nothing; expect reset */
3902 case 1: /* FIN + rFIN */
3903 if (shutdown(fd
[1], SHUT_WR
) != 0) e(0);
3906 * The FIN cannot yet be sent due to the zero-sized receive
3907 * window. Make some room so that it can be sent.
3910 case 2: /* FIN + ACK */
3911 case 3: /* rFIN + FIN */
3912 if (recv(fd
[1], buf
, sizeof(buf
), 0) <= 0) e(0);
3918 if (setsockopt(fd
[1], SOL_SOCKET
, SO_LINGER
, &l
,
3919 sizeof(l
)) != 0) e(0);
3921 if (close(fd
[1]) != 0) e(0);
3930 * Make absolutely sure that the linger timer has triggered and we do
3931 * not end up exploiting race conditions in the tests below. As a
3932 * result this subtest takes over a minute but at least it has already
3933 * triggered a whole bunch of bugs (and produced lwIP patch #9125).
3937 /* Get the number of seconds spent in the close(2) call. */
3938 if (read(pfd
[1], &val
, sizeof(val
)) != sizeof(val
)) e(0);
3941 * See if the close(2) call took as long as expected and check that the
3942 * other side of the connection sees either EOF or a reset as expected.
3950 if (val
!= linger
* 2) e(0);
3954 /* See if the connection was indeed reset. */
3955 while ((res
= recv(fd
[1], buf
, sizeof(buf
), 0)) > 0)
3957 if (res
!= -1) e(0);
3958 if (errno
!= ECONNRESET
) e(0);
3960 if (val
!= ((onoff
&& !nb
) || intr
)) e(0);
3962 /* Check for EOF unless we already closed the socket. */
3964 while ((res
= recv(fd
[1], buf
, sizeof(buf
), 0)) > 0)
3971 if (fd
[1] != -1 && close(fd
[1]) != 0) e(0);
3973 if (close(pfd
[1]) != 0) e(0);
3975 if (wait(&status
) != pid
) e(0);
3976 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) e(0);
3980 * Test SO_LINGER support in various configurations. It is worth noting that I
3981 * implemented a somewhat broken version of SO_LINGER because lwIP does not
3982 * allow for proper detection of our FIN being acknowledged in all cases (this
3983 * is documented in the service). As a result, a close(2) call may return
3984 * earlier than it is supposed to, namely as soon as 1) we sent a FIN, and
3985 * 2) we received a FIN from the other side. We also test the somewhat broken
3986 * behavior here, as above all else the aim is to make sure that the service
3987 * code works as expected.
3998 * In all of the following scenarios, close(2) should only ever return
3999 * success, so that the caller knows that the file descriptor has been
4002 for (nb
= 0; nb
<= 1; nb
++) {
4004 * SO_LINGER off: the close(2) call should return immediately,
4005 * and the connection should be closed in the background.
4007 for (mode
= 1; mode
<= 4; mode
++)
4008 sub91u(nb
, mode
, 0, 0, 0);
4011 * SO_LINGER on with a zero timeout: the close(2) call should
4012 * return immediately, and the connection should be reset.
4014 sub91u(nb
, 0, 0, 1, 0);
4017 * SO_LINGER on with a non-zero timeout: the close(2) call
4018 * should return immediately for non-blocking sockets only, and
4019 * otherwise as soon as either the connection is closed or the
4020 * timeout triggers, in which case the connection is reset.
4022 for (mode
= 0; mode
<= 4; mode
++)
4023 sub91u(nb
, mode
, 0, 1, 1);
4027 * Test signal-interrupting blocked close(2) calls with SO_LINGER. In
4028 * such cases, the close(2) should return EINPROGRESS to indicate that
4029 * the file descriptor has been closed, and the original close action
4030 * (with the original timeout) should proceed in the background.
4032 for (mode
= 0; mode
<= 4; mode
++)
4033 sub91u(0, mode
, 1, 1, 1);
4037 * Test shutdown on listening TCP sockets.
4042 struct sockaddr_in sin
;
4045 int fd
, fd2
, fd3
, fl
;
4047 memset(&sin
, 0, sizeof(sin
));
4048 sin
.sin_family
= AF_INET
;
4049 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
4051 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) e(0);
4053 if (bind(fd
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
4056 if (getsockname(fd
, (struct sockaddr
*)&sin
, &len
) != 0) e(0);
4057 if (len
!= sizeof(sin
)) e(0);
4059 if (listen(fd
, 1) != 0) e(0);
4061 if ((fd2
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) e(0);
4063 if (connect(fd2
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
4065 if (shutdown(fd
, how
) != 0) e(0);
4068 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin
, &len
)) < 0) e(0);
4069 if (len
!= sizeof(sin
)) e(0);
4071 if (write(fd2
, "A", 1) != 1) e(0);
4072 if (read(fd3
, &c
, 1) != 1) e(0);
4075 if (write(fd3
, "B", 1) != 1) e(0);
4076 if (read(fd2
, &c
, 1) != 1) e(0);
4080 if (accept(fd
, (struct sockaddr
*)&sin
, &len
) != -1) e(0);
4081 if (errno
!= ECONNABORTED
) e(0);
4083 if ((fl
= fcntl(fd
, F_GETFL
)) == -1) e(0);
4084 if (fcntl(fd
, F_SETFL
, fl
| O_NONBLOCK
) != 0) e(0);
4087 if (accept(fd
, (struct sockaddr
*)&sin
, &len
) != -1) e(0);
4088 if (errno
!= ECONNABORTED
) e(0);
4090 if (close(fd3
) != 0) e(0);
4091 if (close(fd2
) != 0) e(0);
4092 if (close(fd
) != 0) e(0);
4096 * Test shutdown on listening TCP sockets. This test is derived from test90x.
4101 const int hows
[] = { SHUT_RD
, SHUT_WR
, SHUT_RDWR
};
4106 for (i
= 0; i
< __arraycount(hows
); i
++)
4111 * Test basic sysctl(2) socket enumeration support.
4116 struct kinfo_pcb ki
;
4117 struct sockaddr_in lsin
, rsin
;
4118 struct sockaddr_in6 lsin6
, rsin6
;
4120 uint16_t local_port
, remote_port
;
4122 int fd
[2], val
, sndbuf
, rcvbuf
;
4129 get_tcp_pair(AF_INET
, SOCK_STREAM
, 0, fd
);
4132 if (setsockopt(fd
[1], IPPROTO_TCP
, TCP_NODELAY
, &val
,
4133 sizeof(val
)) != 0) e(0);
4136 if (getsockname(fd
[0], (struct sockaddr
*)&lsin
, &len
) != 0) e(0);
4137 if (len
!= sizeof(lsin
)) e(0);
4138 local_port
= ntohs(lsin
.sin_port
);
4140 if (getpeername(fd
[0], (struct sockaddr
*)&rsin
, &len
) != 0) e(0);
4141 if (len
!= sizeof(rsin
)) e(0);
4142 remote_port
= ntohs(rsin
.sin_port
);
4144 if (send(fd
[0], "ABCDE", 5, 0) != 5) e(0);
4146 /* Allow the data to reach the other side and be acknowledged. */
4149 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, local_port
,
4150 remote_port
, &ki
) != 1) e(0);
4151 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4152 if (ki
.ki_tstate
!= TCPS_ESTABLISHED
) e(0);
4153 if (!(ki
.ki_tflags
& TF_NODELAY
)) e(0);
4154 if (memcmp(&ki
.ki_src
, &lsin
, sizeof(lsin
)) != 0) e(0);
4155 if (memcmp(&ki
.ki_dst
, &rsin
, sizeof(rsin
)) != 0) e(0);
4156 if (ki
.ki_sndq
!= 0) e(0);
4157 if (ki
.ki_rcvq
!= 0) e(0);
4159 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
, local_port
,
4160 remote_port
, &ki
) != 0) e(0);
4162 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, remote_port
,
4163 local_port
, &ki
) != 1) e(0);
4164 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4165 if (ki
.ki_tstate
!= TCPS_ESTABLISHED
) e(0);
4166 if (ki
.ki_tflags
& TF_NODELAY
) e(0);
4167 if (memcmp(&ki
.ki_src
, &rsin
, sizeof(rsin
)) != 0) e(0);
4168 if (memcmp(&ki
.ki_dst
, &lsin
, sizeof(lsin
)) != 0) e(0);
4169 if (ki
.ki_sndq
!= 0) e(0);
4170 if (ki
.ki_rcvq
!= 5) e(0);
4172 if (recv(fd
[1], buf
, sizeof(buf
), 0) != 5) e(0);
4174 if (close(fd
[0]) != 0) e(0);
4175 if (close(fd
[1]) != 0) e(0);
4177 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, local_port
,
4178 remote_port
, &ki
) != 1) e(0);
4179 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4180 if (ki
.ki_tstate
!= TCPS_TIME_WAIT
) e(0);
4181 if (ki
.ki_sndq
!= 0) e(0);
4182 if (ki
.ki_rcvq
!= 0) e(0);
4184 /* Test IPv6 sockets as well. */
4185 get_tcp_pair(AF_INET6
, SOCK_STREAM
, 0, fd
);
4187 len
= sizeof(lsin6
);
4188 if (getsockname(fd
[0], (struct sockaddr
*)&lsin6
, &len
) != 0) e(0);
4189 if (len
!= sizeof(lsin6
)) e(0);
4190 local_port
= ntohs(lsin6
.sin6_port
);
4192 if (getpeername(fd
[0], (struct sockaddr
*)&rsin6
, &len
) != 0) e(0);
4193 if (len
!= sizeof(rsin6
)) e(0);
4194 remote_port
= ntohs(rsin6
.sin6_port
);
4196 memset(buf
, 0, sizeof(buf
));
4198 /* We fill up the queues so we do not need to sleep in this case. */
4199 (void)get_buf_sizes(SOCK_STREAM
, &sndbuf
, &rcvbuf
);
4201 fill_tcp_bufs(fd
[0], fd
[1], 1 /*fill_send*/, 0 /*delta*/);
4203 if (send(fd
[0], buf
, 1, MSG_DONTWAIT
) != -1) e(0);
4204 if (errno
!= EWOULDBLOCK
) e(0);
4206 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
, local_port
,
4207 remote_port
, &ki
) != 1) e(0);
4208 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4209 if (ki
.ki_tstate
!= TCPS_ESTABLISHED
) e(0);
4210 if (!(ki
.ki_tflags
& TF_NODELAY
)) e(0);
4211 if (memcmp(&ki
.ki_src
, &lsin6
, sizeof(lsin6
)) != 0) e(0);
4212 if (memcmp(&ki
.ki_dst
, &rsin6
, sizeof(rsin6
)) != 0) e(0);
4213 if (ki
.ki_sndq
!= (size_t)sndbuf
) e(0);
4214 if (ki
.ki_rcvq
!= 0) e(0);
4216 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, local_port
,
4217 remote_port
, &ki
) != 0) e(0);
4219 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
,
4220 remote_port
, local_port
, &ki
) != 1) e(0);
4221 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4222 if (ki
.ki_tstate
!= TCPS_ESTABLISHED
) e(0);
4223 if (!(ki
.ki_tflags
& TF_NODELAY
)) e(0);
4224 if (memcmp(&ki
.ki_src
, &rsin6
, sizeof(rsin6
)) != 0) e(0);
4225 if (memcmp(&ki
.ki_dst
, &lsin6
, sizeof(lsin6
)) != 0) e(0);
4226 if (ki
.ki_sndq
!= 0) e(0);
4227 if (ki
.ki_rcvq
!= (size_t)rcvbuf
) e(0);
4229 if (close(fd
[0]) != 0) e(0);
4230 if (close(fd
[1]) != 0) e(0);
4232 /* Bound and listening sockets should show up as well. */
4233 if ((fd
[0] = socket(AF_INET
, SOCK_STREAM
, 0)) < 0) e(0);
4235 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, 0, 0,
4238 memset(&lsin
, 0, sizeof(lsin
));
4239 lsin
.sin_len
= sizeof(lsin
);
4240 lsin
.sin_family
= AF_INET
;
4241 lsin
.sin_port
= htons(TEST_PORT_A
);
4242 lsin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
4243 if (bind(fd
[0], (struct sockaddr
*)&lsin
, sizeof(lsin
)) != 0) e(0);
4245 memset(&rsin
, 0, sizeof(rsin
));
4246 rsin
.sin_len
= sizeof(rsin
);
4247 rsin
.sin_family
= AF_INET
;
4249 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, TEST_PORT_A
,
4251 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4252 if (ki
.ki_tstate
!= TCPS_CLOSED
) e(0);
4253 if (memcmp(&ki
.ki_src
, &lsin
, sizeof(lsin
)) != 0) e(0);
4254 if (memcmp(&ki
.ki_dst
, &rsin
, sizeof(rsin
)) != 0) e(0);
4255 if (ki
.ki_sndq
!= 0) e(0);
4256 if (ki
.ki_rcvq
!= 0) e(0);
4258 if (listen(fd
[0], 1)) e(0);
4260 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, TEST_PORT_A
,
4262 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4263 if (ki
.ki_tstate
!= TCPS_LISTEN
) e(0);
4264 if (memcmp(&ki
.ki_src
, &lsin
, sizeof(lsin
)) != 0) e(0);
4265 if (memcmp(&ki
.ki_dst
, &rsin
, sizeof(rsin
)) != 0) e(0);
4266 if (ki
.ki_sndq
!= 0) e(0);
4267 if (ki
.ki_rcvq
!= 0) e(0);
4269 if (close(fd
[0]) != 0) e(0);
4271 /* Test IPv6 sockets as well. */
4272 if ((fd
[0] = socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
4274 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
, 0, 0,
4278 if (setsockopt(fd
[0], IPPROTO_IPV6
, IPV6_V6ONLY
, &val
,
4279 sizeof(val
)) != 0) e(0);
4281 memset(&lsin6
, 0, sizeof(lsin6
));
4282 lsin6
.sin6_len
= sizeof(lsin6
);
4283 lsin6
.sin6_family
= AF_INET6
;
4284 lsin6
.sin6_port
= htons(TEST_PORT_A
);
4285 memcpy(&lsin6
.sin6_addr
, &in6addr_loopback
, sizeof(lsin6
.sin6_addr
));
4286 if (bind(fd
[0], (struct sockaddr
*)&lsin6
, sizeof(lsin6
)) != 0) e(0);
4288 memset(&rsin6
, 0, sizeof(rsin6
));
4289 rsin6
.sin6_len
= sizeof(rsin6
);
4290 rsin6
.sin6_family
= AF_INET6
;
4292 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
,
4293 TEST_PORT_A
, 0, &ki
) != 1) e(0);
4294 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4295 if (ki
.ki_tstate
!= TCPS_CLOSED
) e(0);
4296 if (memcmp(&ki
.ki_src
, &lsin6
, sizeof(lsin6
)) != 0) e(0);
4297 if (memcmp(&ki
.ki_dst
, &rsin6
, sizeof(rsin6
)) != 0) e(0);
4298 if (!(ki
.ki_pflags
& IN6P_IPV6_V6ONLY
)) e(0);
4300 if (listen(fd
[0], 1)) e(0);
4302 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
,
4303 TEST_PORT_A
, 0, &ki
) != 1) e(0);
4304 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4305 if (ki
.ki_tstate
!= TCPS_LISTEN
) e(0);
4306 if (memcmp(&ki
.ki_src
, &lsin6
, sizeof(lsin6
)) != 0) e(0);
4307 if (memcmp(&ki
.ki_dst
, &rsin6
, sizeof(rsin6
)) != 0) e(0);
4308 if (!(ki
.ki_pflags
& IN6P_IPV6_V6ONLY
)) e(0);
4310 if (close(fd
[0]) != 0) e(0);
4313 * I do not dare binding to ANY so we cannot test IPV6_V6ONLY properly
4314 * here. Instead we repeat the test and ensure the IN6P_IPV6_V6ONLY
4315 * flag accurately represents the current state.
4317 if ((fd
[0] = socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
4319 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
, 0, 0,
4323 if (setsockopt(fd
[0], IPPROTO_IPV6
, IPV6_V6ONLY
, &val
,
4324 sizeof(val
)) != 0) e(0);
4326 if (bind(fd
[0], (struct sockaddr
*)&lsin6
, sizeof(lsin6
)) != 0) e(0);
4328 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
,
4329 TEST_PORT_A
, 0, &ki
) != 1) e(0);
4330 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4331 if (ki
.ki_tstate
!= TCPS_CLOSED
) e(0);
4332 if (memcmp(&ki
.ki_src
, &lsin6
, sizeof(lsin6
)) != 0) e(0);
4333 if (memcmp(&ki
.ki_dst
, &rsin6
, sizeof(rsin6
)) != 0) e(0);
4334 if (!(ki
.ki_pflags
& IN6P_IPV6_V6ONLY
)) e(0);
4336 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, TEST_PORT_A
,
4339 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_TCP
, TEST_PORT_A
,
4342 if (close(fd
[0]) != 0) e(0);
4347 if ((fd
[0] = socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
4349 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP
, 0, 0,
4352 memset(&lsin
, 0, sizeof(lsin
));
4353 lsin
.sin_len
= sizeof(lsin
);
4354 lsin
.sin_family
= AF_INET
;
4355 lsin
.sin_port
= htons(TEST_PORT_A
);
4356 lsin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
4358 memset(&rsin
, 0, sizeof(rsin
));
4359 rsin
.sin_len
= sizeof(rsin
);
4360 rsin
.sin_family
= AF_INET
;
4362 if (bind(fd
[0], (struct sockaddr
*)&lsin
, sizeof(lsin
)) != 0) e(0);
4364 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP
, TEST_PORT_A
,
4366 if (ki
.ki_type
!= SOCK_DGRAM
) e(0);
4367 if (ki
.ki_tstate
!= 0) e(0);
4368 if (memcmp(&ki
.ki_src
, &lsin
, sizeof(lsin
)) != 0) e(0);
4369 if (memcmp(&ki
.ki_dst
, &rsin
, sizeof(rsin
)) != 0) e(0);
4370 if (ki
.ki_sndq
!= 0) e(0);
4371 if (ki
.ki_rcvq
!= 0) e(0);
4373 rsin
.sin_port
= htons(TEST_PORT_B
);
4374 rsin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
4375 if (connect(fd
[0], (struct sockaddr
*)&rsin
, sizeof(rsin
)) != 0) e(0);
4377 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP
, TEST_PORT_A
,
4378 TEST_PORT_B
, &ki
) != 1) e(0);
4379 if (ki
.ki_type
!= SOCK_DGRAM
) e(0);
4380 if (ki
.ki_tstate
!= 0) e(0);
4381 if (memcmp(&ki
.ki_src
, &lsin
, sizeof(lsin
)) != 0) e(0);
4382 if (memcmp(&ki
.ki_dst
, &rsin
, sizeof(rsin
)) != 0) e(0);
4383 if (ki
.ki_sndq
!= 0) e(0);
4384 if (ki
.ki_rcvq
!= 0) e(0);
4386 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP
, TEST_PORT_B
,
4387 TEST_PORT_A
, &ki
) != 0) e(0);
4389 if ((fd
[1] = socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) e(0);
4391 if (bind(fd
[1], (struct sockaddr
*)&rsin
, sizeof(rsin
)) != 0) e(0);
4393 if (sendto(fd
[1], "ABC", 3, 0, (struct sockaddr
*)&lsin
,
4394 sizeof(lsin
)) != 3) e(0);
4396 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP
, TEST_PORT_A
,
4397 TEST_PORT_B
, &ki
) != 1) e(0);
4398 if (ki
.ki_type
!= SOCK_DGRAM
) e(0);
4399 if (ki
.ki_tstate
!= 0) e(0);
4400 if (memcmp(&ki
.ki_src
, &lsin
, sizeof(lsin
)) != 0) e(0);
4401 if (memcmp(&ki
.ki_dst
, &rsin
, sizeof(rsin
)) != 0) e(0);
4402 if (ki
.ki_sndq
!= 0) e(0);
4403 if (ki
.ki_rcvq
< 3) e(0); /* size is rounded up */
4405 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP
,
4406 TEST_PORT_A
, TEST_PORT_B
, &ki
) != 0) e(0);
4408 if (close(fd
[0]) != 0) e(0);
4409 if (close(fd
[1]) != 0) e(0);
4411 /* Test IPv6 sockets as well. */
4412 if ((fd
[0] = socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
4414 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP
, 0, 0,
4417 memset(&lsin6
, 0, sizeof(lsin6
));
4418 lsin6
.sin6_len
= sizeof(lsin6
);
4419 lsin6
.sin6_family
= AF_INET6
;
4420 lsin6
.sin6_port
= htons(TEST_PORT_A
);
4421 memcpy(&lsin6
.sin6_addr
, &in6addr_loopback
, sizeof(lsin6
.sin6_addr
));
4422 if (bind(fd
[0], (struct sockaddr
*)&lsin6
, sizeof(lsin6
)) != 0) e(0);
4424 memset(&rsin6
, 0, sizeof(rsin6
));
4425 rsin6
.sin6_len
= sizeof(rsin6
);
4426 rsin6
.sin6_family
= AF_INET6
;
4428 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP
,
4429 TEST_PORT_A
, 0, &ki
) != 1) e(0);
4430 if (ki
.ki_type
!= SOCK_DGRAM
) e(0);
4431 if (ki
.ki_tstate
!= 0) e(0);
4432 if (memcmp(&ki
.ki_src
, &lsin6
, sizeof(lsin6
)) != 0) e(0);
4433 if (memcmp(&ki
.ki_dst
, &rsin6
, sizeof(rsin6
)) != 0) e(0);
4434 if (ki
.ki_sndq
!= 0) e(0);
4435 if (ki
.ki_rcvq
!= 0) e(0);
4436 if (!(ki
.ki_pflags
& IN6P_IPV6_V6ONLY
)) e(0);
4438 rsin6
.sin6_port
= htons(TEST_PORT_B
);
4439 memcpy(&rsin6
.sin6_addr
, &in6addr_loopback
, sizeof(rsin6
.sin6_addr
));
4440 if (connect(fd
[0], (struct sockaddr
*)&rsin6
, sizeof(rsin6
)) != 0)
4443 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP
,
4444 TEST_PORT_A
, TEST_PORT_B
, &ki
) != 1) e(0);
4445 if (ki
.ki_type
!= SOCK_DGRAM
) e(0);
4446 if (ki
.ki_tstate
!= 0) e(0);
4447 if (memcmp(&ki
.ki_src
, &lsin6
, sizeof(lsin6
)) != 0) e(0);
4448 if (memcmp(&ki
.ki_dst
, &rsin6
, sizeof(rsin6
)) != 0) e(0);
4449 if (ki
.ki_sndq
!= 0) e(0);
4450 if (ki
.ki_rcvq
!= 0) e(0);
4451 if (!(ki
.ki_pflags
& IN6P_IPV6_V6ONLY
)) e(0);
4453 if (close(fd
[0]) != 0) e(0);
4455 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP
,
4456 TEST_PORT_A
, TEST_PORT_B
, &ki
) != 0) e(0);
4460 * Test socket enumeration of sockets using IPv4-mapped IPv6 addresses.
4465 struct sockaddr_in6 sin6
;
4466 struct sockaddr_in sin
;
4468 struct kinfo_pcb ki
;
4469 unsigned short local_port
, remote_port
;
4470 int fd
, fd2
, fd3
, val
;
4475 * Test that information from an IPv6 socket bound to an IPv4-mapped
4476 * IPv6 address is as expected. For socket enumeration, due to lwIP
4477 * limitations we return an IPv4 address instead of an IPv4-mapped IPv6
4478 * address, and that is what this test checks for various sockets.
4480 if ((fd
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
4483 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
4486 memset(&sin6
, 0, sizeof(sin6
));
4487 sin6
.sin6_family
= AF_INET6
;
4488 if (inet_pton(AF_INET6
, "::ffff:"LOOPBACK_IPV4
, &sin6
.sin6_addr
) != 1)
4491 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
4494 if (getsockname(fd
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4495 if (len
!= sizeof(sin6
)) e(0);
4496 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4497 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4498 local_port
= ntohs(sin6
.sin6_port
);
4500 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
, local_port
,
4503 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, local_port
,
4506 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4507 if (ki
.ki_tstate
!= TCPS_CLOSED
) e(0);
4509 memcpy(&sin
, &ki
.ki_src
, sizeof(sin
));
4510 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4511 if (sin
.sin_family
!= AF_INET
) e(0);
4512 if (sin
.sin_port
!= htons(local_port
)) e(0);
4513 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4515 memcpy(&sin
, &ki
.ki_dst
, sizeof(sin
));
4516 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4517 if (sin
.sin_family
!= AF_INET
) e(0);
4518 if (sin
.sin_port
!= htons(0)) e(0);
4519 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_ANY
)) e(0);
4521 if (listen(fd
, 1) != 0) e(0);
4524 * Test that information from an accepted (IPv6) socket is correct
4525 * for a connection from an IPv4 address.
4527 if ((fd2
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) e(0);
4529 memset(&sin
, 0, sizeof(sin
));
4530 sin
.sin_family
= AF_INET
;
4531 sin
.sin_port
= htons(local_port
);
4532 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
4534 if (connect(fd2
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
4537 if (getsockname(fd2
, (struct sockaddr
*)&sin
, &len
) != 0) e(0);
4538 if (len
!= sizeof(sin
)) e(0);
4539 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4540 if (sin
.sin_family
!= AF_INET
) e(0);
4541 remote_port
= ntohs(sin
.sin_port
);
4544 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin6
, &len
)) < 0) e(0);
4545 if (len
!= sizeof(sin6
)) e(0);
4546 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4547 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4548 if (sin6
.sin6_port
!= htons(remote_port
)) e(0);
4549 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4550 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4554 if (getsockname(fd3
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4555 if (len
!= sizeof(sin6
)) e(0);
4556 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4557 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4558 if (sin6
.sin6_port
!= htons(local_port
)) e(0);
4559 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4560 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4564 if (getpeername(fd3
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4565 if (len
!= sizeof(sin6
)) e(0);
4566 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4567 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4568 if (sin6
.sin6_port
!= htons(remote_port
)) e(0);
4569 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4570 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4573 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
, local_port
,
4574 remote_port
, &ki
) != 0) e(0);
4576 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, local_port
,
4577 remote_port
, &ki
) != 1) e(0);
4579 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4580 if (ki
.ki_tstate
!= TCPS_ESTABLISHED
) e(0);
4582 memcpy(&sin
, &ki
.ki_src
, sizeof(sin
));
4583 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4584 if (sin
.sin_family
!= AF_INET
) e(0);
4585 if (sin
.sin_port
!= htons(local_port
)) e(0);
4586 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4588 memcpy(&sin
, &ki
.ki_dst
, sizeof(sin
));
4589 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4590 if (sin
.sin_family
!= AF_INET
) e(0);
4591 if (sin
.sin_port
!= htons(remote_port
)) e(0);
4592 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4594 if (close(fd3
) != 0) e(0);
4595 if (close(fd2
) != 0) e(0);
4597 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
, local_port
,
4598 remote_port
, &ki
) != 0) e(0);
4600 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, local_port
,
4601 remote_port
, &ki
) != 1) e(0);
4603 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4604 if (ki
.ki_tstate
!= TCPS_TIME_WAIT
) e(0);
4606 memcpy(&sin
, &ki
.ki_src
, sizeof(sin
));
4607 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4608 if (sin
.sin_family
!= AF_INET
) e(0);
4609 if (sin
.sin_port
!= htons(local_port
)) e(0);
4610 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4612 memcpy(&sin
, &ki
.ki_dst
, sizeof(sin
));
4613 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4614 if (sin
.sin_family
!= AF_INET
) e(0);
4615 if (sin
.sin_port
!= htons(remote_port
)) e(0);
4616 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4619 * Test that information from a connected (IPv6) socket is correct
4620 * after connecting it to an IPv4 address.
4622 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
4625 if (setsockopt(fd2
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
4628 memset(&sin6
, 0, sizeof(sin6
));
4629 sin6
.sin6_family
= AF_INET6
;
4630 sin6
.sin6_port
= htons(local_port
);
4631 if (inet_pton(AF_INET6
, "::ffff:"LOOPBACK_IPV4
, &sin6
.sin6_addr
) != 1)
4634 if (connect(fd2
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
4637 if (getsockname(fd2
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4638 if (len
!= sizeof(sin6
)) e(0);
4639 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4640 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4641 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4642 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4644 remote_port
= ntohs(sin6
.sin6_port
);
4647 if (getpeername(fd2
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4648 if (len
!= sizeof(sin6
)) e(0);
4649 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4650 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4651 if (sin6
.sin6_port
!= htons(local_port
)) e(0);
4652 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4653 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4656 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
,
4657 remote_port
, local_port
, &ki
) != 0) e(0);
4659 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, remote_port
,
4660 local_port
, &ki
) != 1) e(0);
4662 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4663 if (ki
.ki_tstate
!= TCPS_ESTABLISHED
) e(0);
4665 memcpy(&sin
, &ki
.ki_src
, sizeof(sin
));
4666 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4667 if (sin
.sin_family
!= AF_INET
) e(0);
4668 if (sin
.sin_port
!= htons(remote_port
)) e(0);
4669 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4671 memcpy(&sin
, &ki
.ki_dst
, sizeof(sin
));
4672 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4673 if (sin
.sin_family
!= AF_INET
) e(0);
4674 if (sin
.sin_port
!= htons(local_port
)) e(0);
4675 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4678 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin6
, &len
)) < 0) e(0);
4679 if (len
!= sizeof(sin6
)) e(0);
4680 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4681 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4682 if (sin6
.sin6_port
!= htons(remote_port
)) e(0);
4683 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4684 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4687 if (close(fd2
) != 0) e(0);
4688 if (close(fd3
) != 0) e(0);
4689 if (close(fd
) != 0) e(0);
4692 * Do one more test on an accepted socket, now without binding the
4693 * listening socket to an IPv4-mapped IPv6 address.
4695 if ((fd
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
4698 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
4701 memset(&sin6
, 0, sizeof(sin6
));
4702 sin6
.sin6_family
= AF_INET6
;
4703 memcpy(&sin6
.sin6_addr
, &in6addr_any
, sizeof(sin6
.sin6_addr
));
4705 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
4708 if (getsockname(fd
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4709 if (len
!= sizeof(sin6
)) e(0);
4710 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4711 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4712 local_port
= ntohs(sin6
.sin6_port
);
4714 if (listen(fd
, 1) != 0) e(0);
4716 if ((fd2
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) e(0);
4718 memset(&sin
, 0, sizeof(sin
));
4719 sin
.sin_family
= AF_INET
;
4720 sin
.sin_port
= htons(local_port
);
4721 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
4722 if (connect(fd2
, (struct sockaddr
*)&sin
, sizeof(sin
)) != 0) e(0);
4725 if (getsockname(fd2
, (struct sockaddr
*)&sin
, &len
) != 0) e(0);
4726 if (len
!= sizeof(sin
)) e(0);
4727 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4728 if (sin
.sin_family
!= AF_INET
) e(0);
4729 remote_port
= ntohs(sin
.sin_port
);
4732 if ((fd3
= accept(fd
, (struct sockaddr
*)&sin6
, &len
)) < 0) e(0);
4733 if (len
!= sizeof(sin6
)) e(0);
4734 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4735 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4736 if (sin6
.sin6_port
!= htons(remote_port
)) e(0);
4737 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4738 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4742 if (getsockname(fd3
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4743 if (len
!= sizeof(sin6
)) e(0);
4744 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4745 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4746 if (sin6
.sin6_port
!= htons(local_port
)) e(0);
4747 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4748 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4752 if (getpeername(fd3
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4753 if (len
!= sizeof(sin6
)) e(0);
4754 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4755 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4756 if (sin6
.sin6_port
!= htons(remote_port
)) e(0);
4757 if (!IN6_IS_ADDR_V4MAPPED(&sin6
.sin6_addr
)) e(0);
4758 if (sin6
.sin6_addr
.__u6_addr
.__u6_addr32
[3] != htonl(INADDR_LOOPBACK
))
4761 if (socklib_find_pcb("net.inet6.tcp6.pcblist", IPPROTO_TCP
, local_port
,
4762 remote_port
, &ki
) != 0) e(0);
4764 if (socklib_find_pcb("net.inet.tcp.pcblist", IPPROTO_TCP
, local_port
,
4765 remote_port
, &ki
) != 1) e(0);
4767 if (ki
.ki_type
!= SOCK_STREAM
) e(0);
4768 if (ki
.ki_tstate
!= TCPS_ESTABLISHED
) e(0);
4770 memcpy(&sin
, &ki
.ki_src
, sizeof(sin
));
4771 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4772 if (sin
.sin_family
!= AF_INET
) e(0);
4773 if (sin
.sin_port
!= htons(local_port
)) e(0);
4774 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4776 memcpy(&sin
, &ki
.ki_dst
, sizeof(sin
));
4777 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4778 if (sin
.sin_family
!= AF_INET
) e(0);
4779 if (sin
.sin_port
!= htons(remote_port
)) e(0);
4780 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4782 if (close(fd3
) != 0) e(0);
4783 if (close(fd2
) != 0) e(0);
4784 if (close(fd
) != 0) e(0);
4787 * Do some very simple UDP socket enumeration tests. The rest is
4788 * already tested elsewhere.
4790 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
4793 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
4796 memset(&sin6
, 0, sizeof(sin6
));
4797 sin6
.sin6_family
= AF_INET6
;
4798 if (inet_pton(AF_INET6
, "::ffff:"LOOPBACK_IPV4
, &sin6
.sin6_addr
) != 1)
4801 if (bind(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
4804 if (getsockname(fd
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4805 if (len
!= sizeof(sin6
)) e(0);
4806 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4807 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4808 local_port
= ntohs(sin6
.sin6_port
);
4810 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP
, local_port
,
4813 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP
, local_port
,
4816 if (ki
.ki_type
!= SOCK_DGRAM
) e(0);
4817 if (ki
.ki_tstate
!= 0) e(0);
4819 memcpy(&sin
, &ki
.ki_src
, sizeof(sin
));
4820 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4821 if (sin
.sin_family
!= AF_INET
) e(0);
4822 if (sin
.sin_port
!= htons(local_port
)) e(0);
4823 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4825 memcpy(&sin
, &ki
.ki_dst
, sizeof(sin
));
4826 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4827 if (sin
.sin_family
!= AF_INET
) e(0);
4828 if (sin
.sin_port
!= htons(0)) e(0);
4829 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_ANY
)) e(0);
4831 if (close(fd
) != 0) e(0);
4833 if ((fd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) e(0);
4836 if (setsockopt(fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
)) != 0)
4839 memset(&sin6
, 0, sizeof(sin6
));
4840 sin6
.sin6_family
= AF_INET6
;
4841 sin6
.sin6_port
= htons(TEST_PORT_A
);
4842 if (inet_pton(AF_INET6
, "::ffff:"LOOPBACK_IPV4
, &sin6
.sin6_addr
) != 1)
4845 if (connect(fd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
4848 if (getsockname(fd
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4849 if (len
!= sizeof(sin6
)) e(0);
4850 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
4851 if (sin6
.sin6_family
!= AF_INET6
) e(0);
4852 local_port
= ntohs(sin6
.sin6_port
);
4854 if (socklib_find_pcb("net.inet6.udp6.pcblist", IPPROTO_UDP
, local_port
,
4855 TEST_PORT_A
, &ki
) != 0) e(0);
4857 if (socklib_find_pcb("net.inet.udp.pcblist", IPPROTO_UDP
, local_port
,
4858 TEST_PORT_A
, &ki
) != 1) e(0);
4860 if (ki
.ki_type
!= SOCK_DGRAM
) e(0);
4861 if (ki
.ki_tstate
!= 0) e(0);
4863 memcpy(&sin
, &ki
.ki_src
, sizeof(sin
));
4864 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4865 if (sin
.sin_family
!= AF_INET
) e(0);
4866 if (sin
.sin_port
!= htons(local_port
)) e(0);
4867 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4869 memcpy(&sin
, &ki
.ki_dst
, sizeof(sin
));
4870 if (sin
.sin_len
!= sizeof(sin
)) e(0);
4871 if (sin
.sin_family
!= AF_INET
) e(0);
4872 if (sin
.sin_port
!= htons(TEST_PORT_A
)) e(0);
4873 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
)) e(0);
4875 if (close(fd
) != 0) e(0);
4879 * Test local and remote IPv6 address handling. In particular, test scope IDs
4880 * and IPv4-mapped IPv6 addresses.
4888 socklib_test_addrs(SOCK_STREAM
, 0);
4890 socklib_test_addrs(SOCK_DGRAM
, 0);
4894 * Test low-memory conditions for TCP.
4899 struct sockaddr_in6 sin6
;
4901 unsigned char buf
[CHUNK
];
4903 unsigned int i
, j
, k
;
4906 static int fds
[OPEN_MAX
];
4907 static size_t pos
[OPEN_MAX
];
4908 int lfd
, pfd
[2], val
, sndlen
, rcvlen
, status
;
4913 * We use custom send and receive buffer sizes, such that we can
4914 * trigger the case that we run out of send buffers without causing
4915 * buffers used on the receiving side to empty the buffer pool first.
4916 * While the latter case is not unrealistic for practical scenarios, it
4917 * is not what we want to test here. It would also cause practical
4918 * problems for this test, as the result may be that the loopback
4919 * interface (that we use here) starts dropping packets due to being
4920 * unable to make copies.
4922 * The aim with these two is that the ratio is such that we run into
4923 * the 75% usage limit for the send side without using the other 25%
4924 * for receiving purposes. Since our TCP buffer merging guarantees at
4925 * most a 50% overhead on the receiving side, the minimum ratio of 5:1
4926 * translates to a worst-case ratio is 10:3 which is just above 75%.
4927 * Thus, we should be able to use 80K:16K. Instead, we use 128K:16K,
4928 * because otherwise we will run out of sockets before we run out of
4929 * buffers. After all, we are not generating any traffic on the socket
4930 * pairs in the other direction--something for which we do provision.
4936 * Unfortunately, filling up receive queues is not easy, and for any
4937 * size other than the window size (which is by nature also the minimum
4938 * receive queue length that may be set) we would need to work around
4939 * the same issue described in fill_tcp_bufs(), which would massively
4940 * complicate the implementation of this subtest. For now, make sure
4941 * that inconsistent internal changes will trigger this assert.
4943 assert(rcvlen
== WINDOW_SIZE
);
4945 if ((lfd
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
4947 memset(&sin6
, 0, sizeof(sin6
));
4948 sin6
.sin6_family
= AF_INET6
;
4949 memcpy(&sin6
.sin6_addr
, &in6addr_loopback
, sizeof(sin6
.sin6_addr
));
4951 if (bind(lfd
, (struct sockaddr
*)&sin6
, sizeof(sin6
)) != 0) e(0);
4954 if (getsockname(lfd
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
4956 if (listen(lfd
, 1) != 0) e(0);
4959 * Start a child process for the receiving ends. We have to use
4960 * another process because we aim to open a total concurrent number of
4961 * TCP sockets that exceeds OPEN_MAX.
4963 if (pipe(pfd
) != 0) e(0);
4970 if (close(lfd
) != 0) e(0);
4971 if (close(pfd
[1]) != 0) e(0);
4973 /* Create socket pairs. */
4974 for (i
= 0; ; i
++) {
4975 if (i
== __arraycount(fds
)) e(0);
4977 if ((fds
[i
] = socket(AF_INET6
, SOCK_STREAM
, 0)) < 0)
4980 if (connect(fds
[i
], (struct sockaddr
*)&sin6
,
4981 sizeof(sin6
)) != 0) e(0);
4984 if (setsockopt(fds
[i
], IPPROTO_TCP
, TCP_NODELAY
, &val
,
4985 sizeof(val
)) != 0) e(0);
4987 if (setsockopt(fds
[i
], SOL_SOCKET
, SO_RCVBUF
, &rcvlen
,
4988 sizeof(rcvlen
)) != 0) e(0);
4990 /* Synchronization point A. */
4991 if (read(pfd
[0], &k
, sizeof(k
)) != sizeof(k
)) e(0);
4996 /* Synchronization point B. */
4997 if (read(pfd
[0], &k
, sizeof(k
)) != sizeof(k
)) e(0);
5000 /* Receive some data from one socket. */
5002 for (left
= sizeof(buf
) * 2; left
> 0; left
-= res
) {
5003 res
= recv(fds
[0], buf
, MIN(left
, sizeof(buf
)), 0);
5005 if (res
> left
) e(0);
5007 for (j
= 0; j
< res
; j
++)
5008 if (buf
[j
] != (unsigned char)(pos
[0]++)) e(0);
5011 /* Synchronization point C. */
5012 if (read(pfd
[0], &k
, sizeof(k
)) != sizeof(k
)) e(0);
5016 * Receive all remaining data from all sockets. Do this in two
5017 * steps. First enlarge the receive buffer and empty it, so
5018 * that upon resumption, all remaining data is transferred from
5019 * the sender to the receiver in one go. Then actually wait
5020 * for any remaining data, and the EOF. If we do both in one
5021 * step, this part of the test will take several minutes to
5022 * complete. Note that the last socket needs special treatment
5023 * because its send queue may not have been filled entirely.
5025 for (k
= 0; k
<= i
; k
++) {
5026 if (setsockopt(fds
[i
], SOL_SOCKET
, SO_RCVBUF
, &rcvlen
,
5027 sizeof(rcvlen
)) != 0) e(0);
5029 pos
[k
] = (k
== 0) ? (sizeof(buf
) * 2) : 0;
5031 for (left
= sndlen
+ rcvlen
- pos
[k
]; left
> 0;
5033 res
= recv(fds
[k
], buf
, MIN(left
, sizeof(buf
)),
5035 if (res
== -1 && errno
== EWOULDBLOCK
)
5037 if (res
== 0 && k
== i
) {
5038 pos
[i
] = sndlen
+ rcvlen
;
5042 if (res
> left
) e(0);
5044 for (j
= 0; j
< res
; j
++)
5045 if (buf
[j
] != (unsigned char)(k
+
5050 for (k
= 0; k
<= i
; k
++) {
5051 for (left
= sndlen
+ rcvlen
- pos
[k
]; left
> 0;
5053 res
= recv(fds
[k
], buf
, MIN(left
, sizeof(buf
)),
5055 if (res
== 0 && k
== i
)
5058 if (res
> left
) e(0);
5060 for (j
= 0; j
< res
; j
++)
5061 if (buf
[j
] != (unsigned char)(k
+
5065 if (recv(fds
[k
], buf
, 1, 0) != 0) e(0);
5070 if (close(fds
[i
]) != 0) e(0);
5078 if (close(pfd
[0]) != 0) e(0);
5080 for (i
= 0; ; i
++) {
5081 if (i
== __arraycount(fds
)) e(0);
5084 if ((fds
[i
] = accept(lfd
, (struct sockaddr
*)&sin6
, &len
)) < 0)
5088 if (setsockopt(fds
[i
], IPPROTO_TCP
, TCP_NODELAY
, &val
,
5089 sizeof(val
)) != 0) e(0);
5091 if (setsockopt(fds
[i
], SOL_SOCKET
, SO_SNDBUF
, &sndlen
,
5092 sizeof(sndlen
)) != 0) e(0);
5095 * Try to pump as much data into one end of the socket. This
5096 * may fail at any time due to being out of buffers, so we use
5097 * a send timeout to break the resulting blocking call.
5102 if (setsockopt(fds
[i
], SOL_SOCKET
, SO_SNDTIMEO
, &tv
,
5103 sizeof(tv
)) != 0) e(0);
5106 * Since buffer corruption is most likely to be detected when
5107 * lots of buffers are actually in use, also make sure that we
5108 * (eventually) receive what we send.
5112 for (left
= sndlen
+ rcvlen
; left
> 0; left
-= res
) {
5113 /* One byte at a time, for simplicity.. */
5114 for (j
= sizeof(buf
) - res
; j
< sizeof(buf
); j
++)
5115 buf
[j
] = (unsigned char)(i
+ pos
[i
]++);
5117 res
= send(fds
[i
], buf
, MIN(left
, sizeof(buf
)), 0);
5118 if (res
== -1 && errno
== EWOULDBLOCK
)
5122 if (res
> left
) e(0);
5124 if (res
< sizeof(buf
))
5125 memmove(buf
, &buf
[res
], sizeof(buf
) - res
);
5128 /* Synchronization point A. */
5130 if (write(pfd
[1], &k
, sizeof(k
)) != sizeof(k
)) e(0);
5136 if (close(lfd
) != 0) e(0);
5139 * We should always be able to fill at least two socket pairs' buffers
5140 * completely this way; in fact with a 512x512 pool it should be three,
5141 * but some sockets may be in use in the background. With the default
5142 * settings of the memory pool system, we should ideally be able to get
5143 * up to 96 socket pairs.
5148 * Mix things up a bit by fully shutting down one file descriptor and
5149 * closing another, both on the sending side.
5151 if (shutdown(fds
[1], SHUT_RDWR
) != 0) e(0);
5152 if (close(fds
[2]) != 0) e(0);
5155 * Make sure that when there is buffer space available again, pending
5156 * send() calls get woken up. We do this using a child process that
5157 * blocks on a send() call and a parent process that frees up some
5158 * buffer space by receiving from another socket.
5165 /* Disable the timeout again. */
5169 if (setsockopt(fds
[i
], SOL_SOCKET
, SO_SNDTIMEO
, &tv
,
5170 sizeof(tv
)) != 0) e(0);
5173 * Try sending. This should block until there are more buffers
5176 res
= send(fds
[i
], buf
, MIN(left
, sizeof(buf
)), 0);
5178 if (res
> left
) e(0);
5186 /* Make sure the child's send() call is indeed hanging. */
5189 if (waitpid(pid2
, &status
, WNOHANG
) != 0) e(0);
5191 /* Then receive some data on another socket. */
5193 /* Synchronization point B. */
5195 if (write(pfd
[1], &k
, sizeof(k
)) != sizeof(k
)) e(0);
5197 /* The send() call should now be woken up, eventually. */
5198 if (waitpid(pid2
, &status
, 0) != pid2
) e(0);
5199 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) e(0);
5202 * Shut down all (remaining) sending file descriptors for sending, so
5203 * that we can receive until we get EOF. For all but the last socket,
5204 * we must get the full size of what we intended to send; for the first
5205 * socket, we have already received two buffers worth of data. Note
5206 * that the receipt may take a while, mainly because it takes some time
5207 * for sockets that were previously blocked to get going again.
5209 for (k
= 0; k
<= i
; k
++) {
5210 if (k
!= 1 && k
!= 2 && shutdown(fds
[k
], SHUT_WR
) != 0)
5214 /* Synchronization point C. */
5216 if (write(pfd
[1], &k
, sizeof(k
)) != sizeof(k
)) e(0);
5218 if (close(pfd
[1]) != 0) e(0);
5220 /* Wait for the child to receive everything and terminate. */
5221 if (waitpid(pid
, &status
, 0) != pid
) e(0);
5222 if (!WIFEXITED(status
) || WEXITSTATUS(status
) != 0) e(0);
5226 if (i
!= 2 && close(fds
[i
]) != 0) e(0);
5231 * Test multicast support.
5239 socklib_test_multicast(SOCK_DGRAM
, 0);
5243 * Test that putting an unbound TCP socket in listening mode will bind the
5249 struct sockaddr_in sin
;
5250 struct sockaddr_in6 sin6
;
5256 if ((fd
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) e(0);
5258 if (listen(fd
, 1) != 0) e(0);
5261 if (getsockname(fd
, (struct sockaddr
*)&sin
, &len
) != 0) e(0);
5262 if (len
!= sizeof(sin
)) e(0);
5263 if (sin
.sin_len
!= sizeof(sin
)) e(0);
5264 if (sin
.sin_family
!= AF_INET
) e(0);
5265 if (sin
.sin_port
== htons(0)) e(0);
5266 if (sin
.sin_addr
.s_addr
!= htonl(INADDR_ANY
)) e(0);
5268 if (close(fd
) != 0) e(0);
5270 if ((fd
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
5272 if (listen(fd
, 1) != 0) e(0);
5275 if (getsockname(fd
, (struct sockaddr
*)&sin6
, &len
) != 0) e(0);
5276 if (len
!= sizeof(sin6
)) e(0);
5277 if (sin6
.sin6_len
!= sizeof(sin6
)) e(0);
5278 if (sin6
.sin6_family
!= AF_INET6
) e(0);
5279 if (sin6
.sin6_port
== htons(0)) e(0);
5280 if (memcmp(&sin6
.sin6_addr
, &in6addr_any
, sizeof(sin6
.sin6_addr
)) != 0)
5283 if (close(fd
) != 0) e(0);
5287 * Test for connecting to the same remote TCP endpoint with the same local
5288 * endpoint twice in a row. The second connection should fail due to the
5289 * TIME_WAIT state left behind from the first connection, but this previously
5290 * caused an infinite loop instead. lwIP bug #50498.
5295 struct sockaddr_in6 lsin6
, rsin6
;
5301 if ((fd
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
5303 memset(&rsin6
, 0, sizeof(rsin6
));
5304 rsin6
.sin6_family
= AF_INET6
;
5305 memcpy(&rsin6
.sin6_addr
, &in6addr_loopback
, sizeof(rsin6
.sin6_addr
));
5307 if (bind(fd
, (struct sockaddr
*)&rsin6
, sizeof(rsin6
)) != 0) e(0);
5309 len
= sizeof(rsin6
);
5310 if (getsockname(fd
, (struct sockaddr
*)&rsin6
, &len
) != 0) e(0);
5311 if (len
!= sizeof(rsin6
)) e(0);
5313 if (listen(fd
, 1) != 0) e(0);
5315 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
5317 if (connect(fd2
, (struct sockaddr
*)&rsin6
, sizeof(rsin6
)) != 0) e(0);
5319 if ((fd3
= accept(fd
, (struct sockaddr
*)&lsin6
, &len
)) < 0) e(0);
5320 if (len
!= sizeof(rsin6
)) e(0);
5322 /* The server end must initiate the close for this to work. */
5323 if (close(fd3
) != 0) e(0);
5325 if (close(fd2
) != 0) e(0);
5327 if ((fd2
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) e(0);
5329 if (bind(fd2
, (struct sockaddr
*)&lsin6
, sizeof(lsin6
)) != 0) e(0);
5332 * The timeout should occur almost immediately, due to a shortcut in
5333 * lwIP (which was also the source of the problem here). The actual
5334 * error code is not really important though. In fact, if in the
5335 * future the connection does get established, that is still not an
5336 * issue - in fact, it would be nice to have a working rsh(1), which is
5337 * how this problem showed up in the first place - but at the very
5338 * least the service should keep operating.
5340 if (connect(fd2
, (struct sockaddr
*)&rsin6
, sizeof(rsin6
)) != -1) e(0);
5342 if (close(fd2
) != 0) e(0);
5343 if (close(fd
) != 0) e(0);
5347 * Test program for LWIP TCP/UDP sockets.
5350 main(int argc
, char ** argv
)
5362 for (i
= 0; i
< ITERATIONS
; i
++) {
5363 if (m
& 0x00000001) test91a();
5364 if (m
& 0x00000002) test91b();
5365 if (m
& 0x00000004) test91c();
5366 if (m
& 0x00000008) test91d();
5367 if (m
& 0x00000010) test91e();
5368 if (m
& 0x00000020) test91f();
5369 if (m
& 0x00000040) test91g();
5370 if (m
& 0x00000080) test91h();
5371 if (m
& 0x00000100) test91i();
5372 if (m
& 0x00000200) test91j();
5373 if (m
& 0x00000400) test91k();
5374 if (m
& 0x00000800) test91l();
5375 if (m
& 0x00001000) test91m();
5376 if (m
& 0x00002000) test91n();
5377 if (m
& 0x00004000) test91o();
5378 if (m
& 0x00008000) test91p();
5379 if (m
& 0x00010000) test91q();
5380 if (m
& 0x00020000) test91r();
5381 if (m
& 0x00040000) test91s();
5382 if (m
& 0x00080000) test91t();
5383 if (m
& 0x00100000) test91u();
5384 if (m
& 0x00200000) test91v();
5385 if (m
& 0x00400000) test91w();
5386 if (m
& 0x00800000) test91x();
5387 if (m
& 0x01000000) test91y();
5388 if (m
& 0x02000000) test91z();
5389 if (m
& 0x04000000) test91aa();
5390 if (m
& 0x08000000) test91ab();
5391 if (m
& 0x10000000) test91ac();