xref: /freebsd/tools/regression/sockets/kqueue/kqueue.c (revision 3c4ba5f55438f7afd4f4b0b56f88f2bb505fd6a6)
1 /*-
2  * Copyright (c) 2004 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  * $FreeBSD$
27  */
28 
29 #include <sys/types.h>
30 #include <sys/event.h>
31 #include <sys/socket.h>
32 #include <sys/time.h>
33 
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 
41 static int	curtest = 1;
42 
43 /*-
44  * This test uses UNIX domain socket pairs to perform some basic exercising
45  * of kqueue functionality on sockets.  In particular, testing that for read
46  * and write filters, we see the correct detection of whether reads and
47  * writes should actually be able to occur.
48  *
49  * TODO:
50  * - Test read/write filters for listen/accept sockets.
51  * - Handle the XXXRW below regarding datagram sockets.
52  * - Test that watermark/buffer size "data" fields returned by kqueue are
53  *   correct.
54  * - Check that kqueue does something sensible when the remote endpoing is
55  *   closed.
56  */
57 
58 #define OK(testname)	printf("ok %d - %s\n", curtest, testname); \
59 			curtest++;
60 
61 static void
62 fail(int error, const char *func, const char *socktype, const char *rest)
63 {
64 
65 	printf("not ok %d\n", curtest);
66 
67 	if (socktype == NULL)
68 		printf("# %s(): %s\n", func, strerror(error));
69 	else if (rest == NULL)
70 		printf("# %s(%s): %s\n", func, socktype,
71 		    strerror(error));
72 	else
73 		printf("# %s(%s, %s): %s\n", func, socktype, rest,
74 		    strerror(error));
75 	exit(-1);
76 }
77 
78 static void
79 fail_assertion(const char *func, const char *socktype, const char *rest,
80     const char *assertion)
81 {
82 
83 	printf("not ok %d - %s\n", curtest, assertion);
84 
85 	if (socktype == NULL)
86 		printf("# %s(): assertion %s failed\n", func,
87 		    assertion);
88 	else if (rest == NULL)
89 		printf("# %s(%s): assertion %s failed\n", func,
90 		    socktype, assertion);
91 	else
92 		printf("# %s(%s, %s): assertion %s failed\n", func,
93 		    socktype, rest, assertion);
94 	exit(-1);
95 }
96 
97 /*
98  * Test read kevent on a socket pair: check to make sure endpoint 0 isn't
99  * readable when we start, then write to endpoint 1 and confirm that endpoint
100  * 0 is now readable.  Drain the write, then check that it's not readable
101  * again.  Use non-blocking kqueue operations and socket operations.
102  */
103 static void
104 test_evfilt_read(int kq, int fd[2], const char *socktype)
105 {
106 	struct timespec ts;
107 	struct kevent ke;
108 	ssize_t len;
109 	char ch;
110 	int i;
111 
112 	EV_SET(&ke, fd[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
113 	if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
114 		fail(errno, "kevent", socktype, "EVFILT_READ, EV_ADD");
115 	OK("EVFILT_READ, EV_ADD");
116 
117 	/*
118 	 * Confirm not readable to begin with, no I/O yet.
119 	 */
120 	ts.tv_sec = 0;
121 	ts.tv_nsec = 0;
122 	i = kevent(kq, NULL, 0, &ke, 1, &ts);
123 	if (i == -1)
124 		fail(errno, "kevent", socktype, "EVFILT_READ");
125 	OK("EVFILT_READ");
126 	if (i != 0)
127 		fail_assertion("kevent", socktype, "EVFILT_READ",
128 		    "empty socket unreadable");
129 	OK("empty socket unreadable");
130 
131 	/*
132 	 * Write a byte to one end.
133 	 */
134 	ch = 'a';
135 	len = write(fd[1], &ch, sizeof(ch));
136 	if (len == -1)
137 		fail(errno, "write", socktype, NULL);
138 	OK("write one byte");
139 	if (len != sizeof(ch))
140 		fail_assertion("write", socktype, NULL, "write length");
141 	OK("write one byte length");
142 
143 	/*
144 	 * Other end should now be readable.
145 	 */
146 	ts.tv_sec = 0;
147 	ts.tv_nsec = 0;
148 	i = kevent(kq, NULL, 0, &ke, 1, &ts);
149 	if (i == -1)
150 		fail(errno, "kevent", socktype, "EVFILT_READ");
151 	OK("EVFILT_READ");
152 	if (i != 1)
153 		fail_assertion("kevent", socktype, "EVFILT_READ",
154 		    "non-empty socket unreadable");
155 	OK("non-empty socket unreadable");
156 
157 	/*
158 	 * Read a byte to clear the readable state.
159 	 */
160 	len = read(fd[0], &ch, sizeof(ch));
161 	if (len == -1)
162 		fail(errno, "read", socktype, NULL);
163 	OK("read one byte");
164 	if (len != sizeof(ch))
165 		fail_assertion("read", socktype, NULL, "read length");
166 	OK("read one byte length");
167 
168 	/*
169 	 * Now re-check for readability.
170 	 */
171 	ts.tv_sec = 0;
172 	ts.tv_nsec = 0;
173 	i = kevent(kq, NULL, 0, &ke, 1, &ts);
174 	if (i == -1)
175 		fail(errno, "kevent", socktype, "EVFILT_READ");
176 	OK("EVFILT_READ");
177 	if (i != 0)
178 		fail_assertion("kevent", socktype, "EVFILT_READ",
179 		    "empty socket unreadable");
180 	OK("empty socket unreadable");
181 
182 	EV_SET(&ke, fd[0], EVFILT_READ, EV_DELETE, 0, 0, NULL);
183 	if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
184 		fail(errno, "kevent", socktype, "EVFILT_READ, EV_DELETE");
185 	OK("EVFILT_READ, EV_DELETE");
186 }
187 
188 static void
189 test_evfilt_write(int kq, int fd[2], const char *socktype)
190 {
191 	struct timespec ts;
192 	struct kevent ke;
193 	ssize_t len;
194 	char ch;
195 	int i;
196 
197 	EV_SET(&ke, fd[0], EVFILT_WRITE, EV_ADD, 0, 0, NULL);
198 	if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
199 		fail(errno, "kevent", socktype, "EVFILT_WRITE, EV_ADD");
200 	OK("EVFILE_WRITE, EV_ADD");
201 
202 	/*
203 	 * Confirm writable to begin with, no I/O yet.
204 	 */
205 	ts.tv_sec = 0;
206 	ts.tv_nsec = 0;
207 	i = kevent(kq, NULL, 0, &ke, 1, &ts);
208 	if (i == -1)
209 		fail(errno, "kevent", socktype, "EVFILT_WRITE");
210 	OK("EVFILE_WRITE");
211 	if (i != 1)
212 		fail_assertion("kevent", socktype, "EVFILT_WRITE",
213 		    "empty socket unwritable");
214 	OK("empty socket unwritable");
215 
216 	/*
217 	 * Write bytes into the socket until we can't write anymore.
218 	 */
219 	ch = 'a';
220 	while ((len = write(fd[0], &ch, sizeof(ch))) == sizeof(ch)) {};
221 	if (len == -1 && errno != EAGAIN && errno != ENOBUFS)
222 		fail(errno, "write", socktype, NULL);
223 	OK("write");
224 	if (len != -1 && len != sizeof(ch))
225 		fail_assertion("write", socktype, NULL, "write length");
226 	OK("write length");
227 
228 	/*
229 	 * Check to make sure the socket is no longer writable.
230 	 */
231 	ts.tv_sec = 0;
232 	ts.tv_nsec = 0;
233 	i = kevent(kq, NULL, 0, &ke, 1, &ts);
234 	if (i == -1)
235 		fail(errno, "kevent", socktype, "EVFILT_WRITE");
236 	OK("EVFILT_WRITE");
237 	if (i != 0)
238 		fail_assertion("kevent", socktype, "EVFILT_WRITE",
239 		    "full socket writable");
240 	OK("full socket writable");
241 
242 	EV_SET(&ke, fd[0], EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
243 	if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
244 		fail(errno, "kevent", socktype, "EVFILT_WRITE, EV_DELETE");
245 	OK("EVFILT_WRITE, EV_DELETE");
246 }
247 
248 /*
249  * Basic registration exercise for kqueue(2).  Create several types/brands of
250  * sockets, and confirm that we can register for various events on them.
251  */
252 int
253 main(void)
254 {
255 	int kq, sv[2];
256 
257 	printf("1..49\n");
258 
259 	kq = kqueue();
260 	if (kq == -1)
261 		fail(errno, "kqueue", NULL, NULL);
262 	OK("kqueue()");
263 
264 	/*
265 	 * Create a UNIX domain datagram socket, and attach/test/detach a
266 	 * read filter on it.
267 	 */
268 	if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) == -1)
269 		fail(errno, "socketpair", "PF_UNIX, SOCK_DGRAM", NULL);
270 	OK("socketpair() 1");
271 
272 	if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
273 		fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
274 	OK("fcntl() 1");
275 	if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
276 		fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
277 	OK("fnctl() 2");
278 
279 	test_evfilt_read(kq, sv, "PF_UNIX, SOCK_DGRAM");
280 
281 	if (close(sv[0]) == -1)
282 		fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[0]");
283 	OK("close() 1");
284 	if (close(sv[1]) == -1)
285 		fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[1]");
286 	OK("close() 2");
287 
288 #if 0
289 	/*
290 	 * XXXRW: We disable the write test in the case of datagram sockets,
291 	 * as kqueue can't tell when the remote socket receive buffer is
292 	 * full, whereas the UNIX domain socket implementation can tell and
293 	 * returns ENOBUFS.
294 	 */
295 	/*
296 	 * Create a UNIX domain datagram socket, and attach/test/detach a
297 	 * write filter on it.
298 	 */
299 	if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) == -1)
300 		fail(errno, "socketpair", "PF_UNIX, SOCK_DGRAM", NULL);
301 
302 	if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
303 		fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
304 	if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
305 		fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
306 
307 	test_evfilt_write(kq, sv, "PF_UNIX, SOCK_DGRAM");
308 
309 	if (close(sv[0]) == -1)
310 		fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[0]");
311 	if (close(sv[1]) == -1)
312 		fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[1]");
313 #endif
314 
315 	/*
316 	 * Create a UNIX domain stream socket, and attach/test/detach a
317 	 * read filter on it.
318 	 */
319 	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
320 		fail(errno, "socketpair", "PF_UNIX, SOCK_STREAM", NULL);
321 	OK("socketpair() 2");
322 
323 	if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
324 		fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
325 	OK("fcntl() 3");
326 	if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
327 		fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
328 	OK("fcntl() 4");
329 
330 	test_evfilt_read(kq, sv, "PF_UNIX, SOCK_STREAM");
331 
332 	if (close(sv[0]) == -1)
333 		fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[0]");
334 	OK("close() 3");
335 	if (close(sv[1]) == -1)
336 		fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[1]");
337 	OK("close() 4");
338 
339 	/*
340 	 * Create a UNIX domain stream socket, and attach/test/detach a
341 	 * write filter on it.
342 	 */
343 	if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
344 		fail(errno, "socketpair", "PF_UNIX, SOCK_STREAM", NULL);
345 	OK("socketpair() 3");
346 
347 	if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
348 		fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
349 	OK("fcntl() 5");
350 	if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
351 		fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
352 	OK("fcntl() 6");
353 
354 	test_evfilt_write(kq, sv, "PF_UNIX, SOCK_STREAM");
355 
356 	if (close(sv[0]) == -1)
357 		fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[0]");
358 	OK("close() 5");
359 	if (close(sv[1]) == -1)
360 		fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[1]");
361 	OK("close() 6");
362 
363 	if (close(kq) == -1)
364 		fail(errno, "close", "kq", NULL);
365 	OK("close() 7");
366 
367 	return (0);
368 }
369