1*5c2921b0SApple OSS Distributions #include <pthread.h>
2*5c2921b0SApple OSS Distributions #include <stdlib.h>
3*5c2921b0SApple OSS Distributions #include <arpa/inet.h>
4*5c2921b0SApple OSS Distributions #include <netinet/in.h>
5*5c2921b0SApple OSS Distributions #include <stdio.h>
6*5c2921b0SApple OSS Distributions #include <sys/socket.h>
7*5c2921b0SApple OSS Distributions #include <sys/types.h>
8*5c2921b0SApple OSS Distributions #include <sys/uio.h>
9*5c2921b0SApple OSS Distributions #include <unistd.h>
10*5c2921b0SApple OSS Distributions #include <darwintest.h>
11*5c2921b0SApple OSS Distributions
12*5c2921b0SApple OSS Distributions static int port = 2020;
13*5c2921b0SApple OSS Distributions static bool server_ready = false;
14*5c2921b0SApple OSS Distributions
15*5c2921b0SApple OSS Distributions static void
client(void)16*5c2921b0SApple OSS Distributions client(void)
17*5c2921b0SApple OSS Distributions {
18*5c2921b0SApple OSS Distributions int i = 0;
19*5c2921b0SApple OSS Distributions while (i < 9000) {
20*5c2921b0SApple OSS Distributions int sock = socket(PF_INET, SOCK_STREAM, 0);
21*5c2921b0SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(sock, "socket");
22*5c2921b0SApple OSS Distributions struct sockaddr_in raddr;
23*5c2921b0SApple OSS Distributions raddr.sin_family = AF_INET;
24*5c2921b0SApple OSS Distributions raddr.sin_port = htons(port);
25*5c2921b0SApple OSS Distributions raddr.sin_addr.s_addr = inet_addr("127.0.0.1");
26*5c2921b0SApple OSS Distributions int res = connect(sock, (struct sockaddr *)&raddr, sizeof(raddr));
27*5c2921b0SApple OSS Distributions if (res < 0 && (errno == EADDRNOTAVAIL || errno == ECONNREFUSED)) {
28*5c2921b0SApple OSS Distributions close(sock);
29*5c2921b0SApple OSS Distributions return;
30*5c2921b0SApple OSS Distributions } else if (res < 0 && errno == ECONNREFUSED) {
31*5c2921b0SApple OSS Distributions } else {
32*5c2921b0SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(res, "connect");
33*5c2921b0SApple OSS Distributions }
34*5c2921b0SApple OSS Distributions close(sock);
35*5c2921b0SApple OSS Distributions i++;
36*5c2921b0SApple OSS Distributions }
37*5c2921b0SApple OSS Distributions }
38*5c2921b0SApple OSS Distributions
39*5c2921b0SApple OSS Distributions static void *
server(void * arg __unused)40*5c2921b0SApple OSS Distributions server(void *arg __unused)
41*5c2921b0SApple OSS Distributions {
42*5c2921b0SApple OSS Distributions int sock = socket(PF_INET, SOCK_STREAM, 0);
43*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sock, "socket");
44*5c2921b0SApple OSS Distributions
45*5c2921b0SApple OSS Distributions struct sockaddr_in laddr;
46*5c2921b0SApple OSS Distributions laddr.sin_family = AF_INET;
47*5c2921b0SApple OSS Distributions laddr.sin_port = htons(port);
48*5c2921b0SApple OSS Distributions laddr.sin_addr.s_addr = 0;
49*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(bind(sock, (struct sockaddr *)&laddr, sizeof(laddr)), "bind");
50*5c2921b0SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(listen(sock, 10), "listen");
51*5c2921b0SApple OSS Distributions server_ready = true;
52*5c2921b0SApple OSS Distributions while (1) {
53*5c2921b0SApple OSS Distributions struct sockaddr_in sin;
54*5c2921b0SApple OSS Distributions socklen_t slen = sizeof(sin);
55*5c2921b0SApple OSS Distributions int c = accept(sock, (struct sockaddr *)&sin, &slen);
56*5c2921b0SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(c, "accept");
57*5c2921b0SApple OSS Distributions char buf[1];
58*5c2921b0SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(read(c, buf, 1), "read");
59*5c2921b0SApple OSS Distributions close(c);
60*5c2921b0SApple OSS Distributions }
61*5c2921b0SApple OSS Distributions return NULL;
62*5c2921b0SApple OSS Distributions }
63*5c2921b0SApple OSS Distributions
64*5c2921b0SApple OSS Distributions T_DECL(accept_race, "Exercises a race condition between socantrcvmore() and accept()", T_META_CHECK_LEAKS(false))
65*5c2921b0SApple OSS Distributions {
66*5c2921b0SApple OSS Distributions // Pick a random port
67*5c2921b0SApple OSS Distributions port += arc4random_uniform(1024);
68*5c2921b0SApple OSS Distributions
69*5c2921b0SApple OSS Distributions pthread_t server_th;
70*5c2921b0SApple OSS Distributions if (pthread_create(&server_th, 0, server, NULL)) {
71*5c2921b0SApple OSS Distributions T_FAIL("pthread_create failed");
72*5c2921b0SApple OSS Distributions }
73*5c2921b0SApple OSS Distributions while (!server_ready) {
74*5c2921b0SApple OSS Distributions sleep(1);
75*5c2921b0SApple OSS Distributions }
76*5c2921b0SApple OSS Distributions client();
77*5c2921b0SApple OSS Distributions }
78