1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2014 Ryan Zezeski
14 */
15
16 /*
17 * Test TCP deferred accept(). Specifically, test the data/httpfilt
18 * socket filter modules. Deferred accept() allows the kernel to defer
19 * the return of accept() on behalf of the application for the purpose
20 * of making sure data is ready so that the first read() call does not
21 * block or return EAGAIN. This test exercises the code path from the
22 * application level, i.e. entire stack is included.
23 *
24 * datafilt - This module is generic TCP deferment. It assures 1 byte
25 * is ready before accept() returns.
26 *
27 * httpfilt - This module is for HTTP/TCP deferment. It guesses if a
28 * request is valid HTTP and defers accept() until the entire request
29 * is ready, sans the body.
30 */
31 #include <arpa/inet.h>
32 #include <errno.h>
33 #include <kstat.h>
34 #include <netinet/in.h>
35 #include <signal.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <strings.h>
41 #include <sys/socket.h>
42 #include <sys/types.h>
43 #include <sys/wait.h>
44 #include <unistd.h>
45
46 #define BUFSIZE 1024
47 #define COMMON_HEAD \
48 "Accept: */*\r\n" \
49 "Host: test.com\r\n" \
50 "User-Agent: test\r\n" \
51 "\r\n"
52 #define DATAFILT "datafilt"
53 #define HTTPFILT "httpfilt"
54 #define NUM_TESTS 12
55 #define PORT 9876
56
57 /*
58 * Values used to indicate client/server state to each other.
59 */
60 enum State {
61 /* client states */
62 CLIENT_CONNECTED,
63 CLIENT_SENT_ALL,
64 CLIENT_SENT_SOME,
65
66 /* server states */
67 SERVER_LISTENING,
68 SERVER_NO_ACCEPT
69 };
70
71 /*
72 * Each test is defined as a tdata structure in the test_data array.
73 * Adding a new test is a matter of making a new tdata structure and
74 * bumping NUM_TESTS.
75 *
76 * td_type The filter to use: HTTPFILT | DATAFILT.
77 *
78 * td_name The name of the test, written to stdout.
79 *
80 * td_msgs An array of data msgs that will be sent by the client()
81 * process.
82 *
83 * td_num_msgs The number of msgs in td_msgs.
84 */
85 struct tdata {
86 char *td_type;
87 char *td_name;
88 char *td_msgs[2];
89 int td_num_msgs;
90 };
91
92 static struct tdata test_data[NUM_TESTS] = {
93 {
94 HTTPFILT,
95 "httpfilt_GET",
96 {"GET /test HTTP/1.1\r\n", COMMON_HEAD},
97 2
98 },
99 {
100 HTTPFILT,
101 "httpfilt_GET_LF_only",
102 {"GET /test HTTP/1.1\n",
103 "Accept: */*\n" \
104 "Host: test.com\n" \
105 "User-Agent: test\n" \
106 "\n"},
107 2
108 },
109 {
110 HTTPFILT,
111 "httpfilt_PUT",
112 {"PUT /test HTTP/1.1\r\n", COMMON_HEAD},
113 2
114 },
115 {
116 HTTPFILT,
117 "httpfilt_POST",
118 {"POST /test HTTP/1.1\r\n", COMMON_HEAD},
119 2
120 },
121 {
122 HTTPFILT,
123 "httpfilt_HEAD",
124 {"HEAD /test HTTP/1.1\r\n", COMMON_HEAD},
125 2
126 },
127 {
128 HTTPFILT,
129 "httpfilt_OPTIONS",
130 {"OPTIONS /test HTTP/1.1\r\n", COMMON_HEAD},
131 2
132 },
133 {
134 HTTPFILT,
135 "httpfilt_TRACE",
136 {"TRACE /test HTTP/1.1\r\n", COMMON_HEAD},
137 2
138 },
139 {
140 HTTPFILT,
141 "httpfilt_CONNECT",
142 {"CONNECT /test HTTP/1.1\r\n", COMMON_HEAD},
143 2
144 },
145 {
146 HTTPFILT,
147 "httpfilt_VERSION-CONTROL",
148 {"VERSION-CONTROL /test HTTP/1.1\r\n", COMMON_HEAD},
149 2
150 },
151 {
152 /*
153 * Verify that a starting space (non-HTTP) is not
154 * deferred.
155 */
156 HTTPFILT,
157 "httpfilt_space",
158 {" some data..."},
159 1
160 },
161 {
162 /* Verify that a bad method is not deferred. */
163 HTTPFILT,
164 "httpfilt_bad_method",
165 {"badmethod /test HTTP/1.1\r\n"},
166 1
167 },
168 {
169 DATAFILT,
170 "datafilt_one_byte",
171 {"X"},
172 1
173 }
174 };
175
176 static int debug = 0;
177
178 static int client(int fd, char **msgs, int num_msgs);
179 static int server(int fd, char *td_type, char **msgs, int num_msgs);
180
181 static void dbg(const char *format, ...);
182 static int msgscmp(char *data, char **msgs, int num_msgs);
183 static int run(struct tdata tdata);
184 static int sendstate(int fd, enum State state);
185 static int waitforstate(int fd, enum State state);
186
187 int
188 main(int argc, char **argv)
189 {
190 int c, rc = 0;
191
192 while ((c = getopt(argc, argv, "d")) != -1) {
193 switch (c) {
194 case 'd':
195 debug = 1;
196 break;
197 default:
198 break;
199 }
200 }
201
202 for (int i = 0; i < NUM_TESTS; i++)
203 rc += run(test_data[i]);
204
205 return (rc);
206 }
207
208 /*
209 * This test is made up of two cooperating processes which share state
210 * updates over a pipe. The sequence diagram below shows the actions
211 * taken on each side of the socket as well as the state messages. The
212 * numbers represent the order, two steps with the same number happen
213 * concurrently. The state messages act as synchronization points; a
214 * process will block until it receives the expected message. Notice
215 * that a server may accept multiple times before the socket is
216 * created, this proves deferment. A non-deferred socket will accept
217 * on the first try.
218 *
219 * CLI SOCK CLIENT SERVER SERVER SOCK
220 * | |
221 * | | (1) listen()
222 * |<--------SERVER_LISTENING-------+
223 * (2) connect() | |
224 * +---------CLIENT_CONNECTED------>|
225 * | | (3) accept()
226 * |<--------SERVER_NO_ACCEPT-------+
227 * (4.x) send() | |
228 * +---------CLIENT_SENT_SOME------>|
229 * | | (5.x) accept()
230 * |<--------SERVER_NO_ACCEPT-------+
231 * | |
232 * +---------CLIENT_SENT_ALL------->|
233 * (6) close() | | (6) accept()
234 * | | (7) recv()
235 * | | (8) close()
236 * | |
237 * = =
238 *
239 */
240 static int
241 run(struct tdata tdata)
242 {
243 int fd[2], rc;
244 pid_t child;
245
246 (void) printf("TEST STARTING: %s\n", tdata.td_name);
247
248 if (pipe(fd) != 0) {
249 perror("failed to create pipe");
250 return (1);
251 }
252
253 child = fork();
254 if (child == 0) {
255 exit(client(fd[1], tdata.td_msgs, tdata.td_num_msgs));
256 } else if (child > 0) {
257 rc = server(fd[0], tdata.td_type, tdata.td_msgs,
258 tdata.td_num_msgs);
259 if (rc != 0)
260 (void) printf("TEST FAILED: %s\n", tdata.td_name);
261 else
262 (void) printf("TEST PASSED: %s\n", tdata.td_name);
263
264 (void) close(fd[0]);
265 (void) close(fd[1]);
266 (void) kill(child, SIGKILL);
267 } else {
268 perror("problem with fork()\n");
269 (void) printf("TEST FAILED: %s\n", tdata.td_name);
270 rc = 1;
271 }
272
273 return (rc);
274 }
275
276 static int
277 server(int fd, char *filt, char **msgs, int num_msgs)
278 {
279 int csock, lsock, ndeferred, status;
280 char buf[BUFSIZE];
281 kstat_ctl_t *kc;
282 kstat_named_t *kn;
283 kstat_t *ks;
284 struct sockaddr_in addr, cliaddr;
285 socklen_t clilen;
286
287 lsock = socket(PF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
288
289 if (setsockopt(lsock, SOL_FILTER, FIL_ATTACH, filt, strlen(filt) + 1) <
290 0) {
291 perror("couldn't set filter");
292 return (1);
293 }
294
295 if (lsock == -1) {
296 perror("socket");
297 return (1);
298 }
299
300 bzero(&addr, sizeof (addr));
301 addr.sin_family = AF_INET;
302 addr.sin_addr.s_addr = htonl(INADDR_ANY);
303 addr.sin_port = htons(PORT);
304 if (bind(lsock, (struct sockaddr *)&addr, sizeof (addr)) < 0) {
305 perror("server failed to bind");
306 return (1);
307 }
308
309 if (listen(lsock, 2) < 0) {
310 perror("listen failed");
311 return (1);
312 }
313
314 dbg("(1) [server] listen()\n");
315
316 char filter_name[1024] = "filter_";
317 (void) strcat(filter_name, filt);
318 kc = kstat_open();
319 ks = kstat_lookup(kc, "sockfs", 0, filter_name);
320 (void) kstat_read(kc, ks, NULL);
321 kn = kstat_data_lookup(ks, "ndeferred");
322 ndeferred = kn->value.ui64;
323
324 if (ndeferred != 0) {
325 (void) fprintf(stderr, "expected 0 deferred conns but got %d\n",
326 ndeferred);
327 return (1);
328 }
329
330 if (sendstate(fd, SERVER_LISTENING) != 0)
331 return (1);
332
333 dbg("---SERVER_LISTENING----->\n");
334
335 if (waitforstate(fd, CLIENT_CONNECTED) != 0)
336 return (1);
337
338 clilen = sizeof (cliaddr);
339 csock = accept(lsock, (struct sockaddr *)&cliaddr, &clilen);
340 if ((csock == -1) && (errno != EAGAIN)) {
341 perror("problem accepting");
342 return (1);
343 } else if (csock != -1) {
344 (void) fprintf(stderr,
345 "server accpeted before any data sent\n");
346 return (1);
347 }
348
349 dbg("(3) [server] accept()\n");
350
351 (void) kstat_chain_update(kc);
352 (void) kstat_read(kc, ks, NULL);
353 kn = kstat_data_lookup(ks, "ndeferred");
354 ndeferred = kn->value.ui64;
355 if (ndeferred != 1) {
356 (void) fprintf(stderr, "expected 1 deferred conns but got %d\n",
357 ndeferred);
358 return (1);
359 }
360
361 if (sendstate(fd, SERVER_NO_ACCEPT) != 0)
362 return (1);
363
364 dbg("---SERVER_NO_ACCEPT--->\n");
365
366 /* The last msg is the final msg. */
367 for (int i = 0; i < num_msgs - 1; i++) {
368 if (waitforstate(fd, CLIENT_SENT_SOME) != 0)
369 return (1);
370
371 csock = accept(lsock, (struct sockaddr *)&cliaddr, &clilen);
372 if ((csock == -1) && (errno != EAGAIN)) {
373 perror("problem accepting");
374 return (1);
375 } else if (csock != -1) {
376 (void) fprintf(stderr,
377 "server accpeted after some data sent\n");
378 return (1);
379 }
380
381 dbg("(5.%d) [server] accept()\n", i);
382
383 if (sendstate(fd, SERVER_NO_ACCEPT) != 0)
384 return (1);
385
386 dbg("---SERVER_NO_ACCEPT--->\n");
387
388 }
389
390 if (waitforstate(fd, CLIENT_SENT_ALL) != 0)
391 return (1);
392
393 csock = accept(lsock, (struct sockaddr *)&cliaddr, &clilen);
394 if (csock == -1) {
395 perror("problem accepting");
396 return (1);
397 }
398
399 dbg("(6) [server] accept()\n");
400
401 bzero(&buf, BUFSIZE);
402 if (recv(csock, buf, BUFSIZE, 0) == -1) {
403 perror("problemn receiving data");
404 return (1);
405 }
406
407 dbg("(7) [server] recv()\n");
408
409 if (msgscmp(buf, msgs, num_msgs) != 0) {
410 (void) fprintf(stderr, "data modified\n");
411 return (1);
412 }
413
414 (void) close(csock);
415 (void) close(lsock);
416
417 dbg("(8) [server] close()\n");
418
419 (void) wait(&status);
420 return (status);
421 }
422
423 static int
424 client(int fd, char **msgs, int num_msgs)
425 {
426 int sock;
427 size_t sz;
428 struct sockaddr_in addr;
429
430 if (waitforstate(fd, SERVER_LISTENING) != 0)
431 return (1);
432
433 bzero(&addr, sizeof (addr));
434 addr.sin_family = AF_INET;
435 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
436 addr.sin_port = htons(PORT);
437
438 sock = socket(AF_INET, SOCK_STREAM, 0);
439 if (sock < 0) {
440 perror("cannot create client socket");
441 return (1);
442 }
443
444 if (connect(sock, (struct sockaddr *)&addr, sizeof (addr)) < 0) {
445 (void) printf("failed to connect: %d\n", errno);
446 perror("cannot connect to server");
447 return (1);
448 }
449
450 dbg("(2) [client] connect()\n");
451
452 if (sendstate(fd, CLIENT_CONNECTED) != 0)
453 return (1);
454
455 dbg("<---CLIENT_CONNECTED-----\n");
456
457 if (waitforstate(fd, SERVER_NO_ACCEPT) != 0)
458 return (1);
459
460 for (int i = 0; i < num_msgs; i++) {
461 size_t len = strlen(msgs[i]);
462 sz = send(sock, msgs[i], len, 0);
463 if (sz != len) {
464 (void) fprintf(stderr,
465 "client sent %zu bytes, but should have sent %zu\n",
466 sz, len);
467 return (1);
468 }
469
470 dbg("(4.%d) [client] send()\n", i);
471
472 if (i == num_msgs - 1)
473 break;
474
475 if (sendstate(fd, CLIENT_SENT_SOME) != 0)
476 return (1);
477
478 dbg("<---CLIENT_SENT_SOME-----\n");
479
480 if (waitforstate(fd, SERVER_NO_ACCEPT) != 0)
481 return (1);
482 }
483
484 if (sendstate(fd, CLIENT_SENT_ALL) != 0)
485 return (1);
486
487 dbg("<---CLIENT_SENT_ALL-----\n");
488 (void) close(sock);
489 dbg("(6) [client] close()\n");
490
491 return (0);
492 }
493
494 /* Send a debug msg to stdout. */
495 static void
496 dbg(const char *format, ...)
497 {
498 va_list args;
499
500 if (!debug) {
501 return;
502 }
503
504 va_start(args, format);
505 (void) vprintf(format, args);
506 va_end(args);
507 (void) fflush(stdout);
508 }
509
510 /*
511 * Test for byte-for-byte equality between data and msgs. Return 0 if
512 * equal, 1 otherwise.
513 */
514 static int
515 msgscmp(char *data, char **msgs, int num_msgs)
516 {
517 for (int i = 0, offset = 0; i < num_msgs; i++) {
518 int len = strlen(msgs[i]);
519 if (memcmp(&data[offset], msgs[i], len) != 0)
520 return (1);
521
522 offset += len;
523 }
524
525 return (0);
526 }
527
528 /* Send a state across the pipe. */
529 static int sendstate(int fd, enum State state)
530 {
531 size_t sz;
532
533 sz = write(fd, &state, sizeof (int));
534 return ((sz == sizeof (int)) ? 0 : 1);
535 }
536
537 /* Block on the given state. */
538 static int waitforstate(int fd, enum State state)
539 {
540 int i;
541 size_t sz;
542
543 sz = read(fd, &i, sizeof (int));
544 if (sz != sizeof (int)) {
545 (void) fprintf(stderr, "couldn't read int\n");
546 return (1);
547 }
548
549 if (i != state) {
550 (void) fprintf(stderr,
551 "saw state %d but expected %d\n", i, state);
552 return (1);
553 }
554
555 return (0);
556 }