Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/regression/sockets/unix_sendtorace/unix_sendtorace.c
48254 views
1
/*-
2
* Copyright (c) 2006 Robert N. M. Watson
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
/*
28
* Attempts to exercise UNIX domain socket races relating to the non-atomic
29
* connect-and-send properties of sendto(). As the result of such a race is
30
* a kernel panic, this test simply completes or doesn't.
31
*
32
* XXX: Despite implementing support for sendto() on stream sockets with
33
* implied connect, the appropriate flag isn't set in the FreeBSD kernel so
34
* it does not work. For now, don't call the stream test.
35
*/
36
37
#include <sys/types.h>
38
#include <sys/socket.h>
39
#include <sys/un.h>
40
41
#include <err.h>
42
#include <signal.h>
43
#include <string.h>
44
#include <unistd.h>
45
46
#define ITERATIONS 1000000
47
48
static char socket_path[] = "tmp.XXXXXX";
49
50
static void
51
stream_server(int listenfd)
52
{
53
int acceptfd;
54
55
while (1) {
56
acceptfd = accept(listenfd, NULL, NULL);
57
if (acceptfd < 0) {
58
warn("stream_server: accept");
59
continue;
60
}
61
sleep(1);
62
close(acceptfd);
63
}
64
}
65
66
static void
67
stream_client(void)
68
{
69
struct sockaddr_un sun;
70
ssize_t len;
71
char c = 0;
72
int fd, i;
73
74
bzero(&sun, sizeof(sun));
75
sun.sun_len = sizeof(sun);
76
sun.sun_family = AF_UNIX;
77
strcpy(sun.sun_path, socket_path);
78
for (i = 0; i < ITERATIONS; i++) {
79
fd = socket(PF_UNIX, SOCK_STREAM, 0);
80
if (fd < 0) {
81
warn("stream_client: socket");
82
return;
83
}
84
len = sendto(fd, &c, sizeof(c), 0, (struct sockaddr *)&sun,
85
sizeof(sun));
86
if (len < 0)
87
warn("stream_client: sendto");
88
close(fd);
89
}
90
}
91
92
static void
93
stream_test(void)
94
{
95
struct sockaddr_un sun;
96
pid_t childpid;
97
int listenfd;
98
99
listenfd = socket(PF_UNIX, SOCK_STREAM, 0);
100
if (listenfd < 0)
101
err(-1, "stream_test: socket");
102
103
bzero(&sun, sizeof(sun));
104
sun.sun_len = sizeof(sun);
105
sun.sun_family = AF_UNIX;
106
strcpy(sun.sun_path, socket_path);
107
108
if (bind(listenfd, (struct sockaddr *)&sun, sizeof(sun)) < 0)
109
err(-1, "stream_test: bind");
110
111
if (listen(listenfd, -1) < 0)
112
err(-1, "stream_test: listen");
113
114
childpid = fork();
115
if (childpid < 0)
116
err(-1, "stream_test: fork");
117
118
if (childpid != 0) {
119
sleep(1);
120
stream_client();
121
kill(childpid, SIGTERM);
122
sleep(1);
123
} else
124
stream_server(listenfd);
125
126
(void)unlink(socket_path);
127
}
128
129
static void
130
datagram_server(int serverfd)
131
{
132
ssize_t len;
133
char c;
134
135
while (1) {
136
len = recv(serverfd, &c, sizeof(c), 0);
137
if (len < 0)
138
warn("datagram_server: recv");
139
}
140
}
141
142
static void
143
datagram_client(void)
144
{
145
struct sockaddr_un sun;
146
ssize_t len;
147
char c = 0;
148
int fd, i;
149
150
bzero(&sun, sizeof(sun));
151
sun.sun_len = sizeof(sun);
152
sun.sun_family = AF_UNIX;
153
strcpy(sun.sun_path, socket_path);
154
for (i = 0; i < ITERATIONS; i++) {
155
fd = socket(PF_UNIX, SOCK_DGRAM, 0);
156
if (fd < 0) {
157
warn("datagram_client: socket");
158
return;
159
}
160
len = sendto(fd, &c, sizeof(c), 0, (struct sockaddr *)&sun,
161
sizeof(sun));
162
if (len < 0)
163
warn("datagram_client: sendto");
164
close(fd);
165
}
166
}
167
168
static void
169
datagram_test(void)
170
{
171
struct sockaddr_un sun;
172
pid_t childpid;
173
int serverfd;
174
175
serverfd = socket(PF_UNIX, SOCK_DGRAM, 0);
176
if (serverfd < 0)
177
err(-1, "datagram_test: socket");
178
179
bzero(&sun, sizeof(sun));
180
sun.sun_len = sizeof(sun);
181
sun.sun_family = AF_UNIX;
182
strcpy(sun.sun_path, socket_path);
183
184
if (bind(serverfd, (struct sockaddr *)&sun, sizeof(sun)) < 0)
185
err(-1, "datagram_test: bind");
186
187
childpid = fork();
188
if (childpid < 0)
189
err(-1, "datagram_test: fork");
190
191
if (childpid != 0) {
192
sleep(1);
193
datagram_client();
194
kill(childpid, SIGTERM);
195
sleep(1);
196
} else
197
datagram_server(serverfd);
198
199
(void)unlink(socket_path);
200
}
201
202
int
203
main(void)
204
{
205
206
if (mkstemp(socket_path) == -1)
207
err(1, "mkstemp failed");
208
(void)unlink(socket_path);
209
datagram_test();
210
if (0)
211
stream_test();
212
return (0);
213
}
214
215