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
41static 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
61static void
62fail(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
78static void
79fail_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 */
103static void
104test_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
188static void
189test_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 */
252int
253main(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