1 /* $NetBSD: socket_test.c,v 1.1.1.6 2014/12/10 03:34:44 christos Exp $ */
2
3 /*
4 * Copyright (C) 2011-2014 Internet Systems Consortium, Inc. ("ISC")
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /* Id */
20
21 /*! \file */
22
23 #include <config.h>
24
25 #include <atf-c.h>
26
27 #include <unistd.h>
28 #include <time.h>
29
30 #include <isc/socket.h>
31
32 #include "../task_p.h"
33 #include "../unix/socket_p.h"
34 #include "isctest.h"
35
36 static isc_boolean_t recv_dscp;
37 static unsigned int recv_dscp_value;
38
39 /*
40 * Helper functions
41 */
42
43 typedef struct {
44 isc_boolean_t done;
45 isc_result_t result;
46 isc_socket_t *socket;
47 } completion_t;
48
49 static void
completion_init(completion_t * completion)50 completion_init(completion_t *completion) {
51 completion->done = ISC_FALSE;
52 completion->socket = NULL;
53 }
54
55 static void
accept_done(isc_task_t * task,isc_event_t * event)56 accept_done(isc_task_t *task, isc_event_t *event) {
57 isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
58 completion_t *completion = event->ev_arg;
59
60 UNUSED(task);
61
62 completion->result = nevent->result;
63 completion->done = ISC_TRUE;
64 if (completion->result == ISC_R_SUCCESS)
65 completion->socket = nevent->newsocket;
66
67 isc_event_free(&event);
68 }
69
70 static void
event_done(isc_task_t * task,isc_event_t * event)71 event_done(isc_task_t *task, isc_event_t *event) {
72 isc_socketevent_t *dev;
73 completion_t *completion = event->ev_arg;
74
75 UNUSED(task);
76
77 dev = (isc_socketevent_t *) event;
78 completion->result = dev->result;
79 completion->done = ISC_TRUE;
80 if ((dev->attributes & ISC_SOCKEVENTATTR_DSCP) != 0) {
81 recv_dscp = ISC_TRUE;
82 recv_dscp_value = dev->dscp;;
83 } else
84 recv_dscp = ISC_FALSE;
85 isc_event_free(&event);
86 }
87
88 static isc_result_t
waitfor(completion_t * completion)89 waitfor(completion_t *completion) {
90 int i = 0;
91 while (!completion->done && i++ < 5000) {
92 #ifndef ISC_PLATFORM_USETHREADS
93 while (isc__taskmgr_ready(taskmgr))
94 isc__taskmgr_dispatch(taskmgr);
95 #endif
96 isc_test_nap(1000);
97 }
98 if (completion->done)
99 return (ISC_R_SUCCESS);
100 return (ISC_R_FAILURE);
101 }
102
103 #if 0
104 static isc_result_t
105 waitfor(completion_t *completion) {
106 int i = 0;
107 while (!completion->done && i++ < 5000) {
108 waitbody();
109 }
110 if (completion->done)
111 return (ISC_R_SUCCESS);
112 return (ISC_R_FAILURE);
113 }
114 #endif
115
116 static void
waitbody(void)117 waitbody(void) {
118 #ifndef ISC_PLATFORM_USETHREADS
119 struct timeval tv;
120 isc_socketwait_t *swait = NULL;
121
122 while (isc__taskmgr_ready(taskmgr))
123 isc__taskmgr_dispatch(taskmgr);
124 if (socketmgr != NULL) {
125 tv.tv_sec = 0;
126 tv.tv_usec = 1000 ;
127 if (isc__socketmgr_waitevents(socketmgr, &tv, &swait) > 0)
128 isc__socketmgr_dispatch(socketmgr, swait);
129 } else
130 #endif
131 isc_test_nap(1000);
132 }
133
134 static isc_result_t
waitfor2(completion_t * c1,completion_t * c2)135 waitfor2(completion_t *c1, completion_t *c2) {
136 int i = 0;
137
138 while (!(c1->done && c2->done) && i++ < 5000) {
139 waitbody();
140 }
141 if (c1->done && c2->done)
142 return (ISC_R_SUCCESS);
143 return (ISC_R_FAILURE);
144 }
145
146 /*
147 * Individual unit tests
148 */
149
150 /* Test UDP sendto/recv (IPv4) */
151 ATF_TC(udp_sendto);
ATF_TC_HEAD(udp_sendto,tc)152 ATF_TC_HEAD(udp_sendto, tc) {
153 atf_tc_set_md_var(tc, "descr", "UDP sendto/recv");
154 }
ATF_TC_BODY(udp_sendto,tc)155 ATF_TC_BODY(udp_sendto, tc) {
156 isc_result_t result;
157 isc_sockaddr_t addr1, addr2;
158 struct in_addr in;
159 isc_socket_t *s1 = NULL, *s2 = NULL;
160 isc_task_t *task = NULL;
161 char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
162 completion_t completion;
163 isc_region_t r;
164
165 UNUSED(tc);
166
167 result = isc_test_begin(NULL, ISC_TRUE);
168 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
169
170 /*
171 * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to
172 * each other.
173 */
174 in.s_addr = inet_addr("127.0.0.1");
175 isc_sockaddr_fromin(&addr1, &in, 5444);
176 isc_sockaddr_fromin(&addr2, &in, 5445);
177
178 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
179 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
180 result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
181 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
182
183 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
184 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
185 result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
186 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
187
188 result = isc_task_create(taskmgr, 0, &task);
189 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
190
191 strcpy(sendbuf, "Hello");
192 r.base = (void *) sendbuf;
193 r.length = strlen(sendbuf) + 1;
194
195 completion_init(&completion);
196 result = isc_socket_sendto(s1, &r, task, event_done, &completion,
197 &addr2, NULL);
198 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
199 waitfor(&completion);
200 ATF_CHECK(completion.done);
201 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
202
203 r.base = (void *) recvbuf;
204 r.length = BUFSIZ;
205 completion_init(&completion);
206 result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
207 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
208 waitfor(&completion);
209 ATF_CHECK(completion.done);
210 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
211 ATF_CHECK_STREQ(recvbuf, "Hello");
212
213 isc_task_detach(&task);
214
215 isc_socket_detach(&s1);
216 isc_socket_detach(&s2);
217
218 isc_test_end();
219 }
220
221 /* Test UDP sendto/recv with duplicated socket */
222 ATF_TC(udp_dup);
ATF_TC_HEAD(udp_dup,tc)223 ATF_TC_HEAD(udp_dup, tc) {
224 atf_tc_set_md_var(tc, "descr", "duplicated socket sendto/recv");
225 }
ATF_TC_BODY(udp_dup,tc)226 ATF_TC_BODY(udp_dup, tc) {
227 isc_result_t result;
228 isc_sockaddr_t addr1, addr2;
229 struct in_addr in;
230 isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
231 isc_task_t *task = NULL;
232 char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
233 completion_t completion;
234 isc_region_t r;
235
236 UNUSED(tc);
237
238 result = isc_test_begin(NULL, ISC_TRUE);
239 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
240
241 /*
242 * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to
243 * each other.
244 */
245 in.s_addr = inet_addr("127.0.0.1");
246 isc_sockaddr_fromin(&addr1, &in, 5444);
247 isc_sockaddr_fromin(&addr2, &in, 5445);
248
249 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
250 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
251 result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
252 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
253
254 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
255 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
256 result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
257 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
258
259 result = isc_socket_dup(s2, &s3);
260 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
261
262 result = isc_task_create(taskmgr, 0, &task);
263 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
264
265 strcpy(sendbuf, "Hello");
266 r.base = (void *) sendbuf;
267 r.length = strlen(sendbuf) + 1;
268
269 completion_init(&completion);
270 result = isc_socket_sendto(s1, &r, task, event_done, &completion,
271 &addr2, NULL);
272 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
273 waitfor(&completion);
274 ATF_CHECK(completion.done);
275 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
276
277 strcpy(sendbuf, "World");
278 r.base = (void *) sendbuf;
279 r.length = strlen(sendbuf) + 1;
280
281 completion_init(&completion);
282 result = isc_socket_sendto(s1, &r, task, event_done, &completion,
283 &addr2, NULL);
284 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
285 waitfor(&completion);
286 ATF_CHECK(completion.done);
287 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
288
289 r.base = (void *) recvbuf;
290 r.length = BUFSIZ;
291 completion_init(&completion);
292 result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
293 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
294 waitfor(&completion);
295 ATF_CHECK(completion.done);
296 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
297 ATF_CHECK_STREQ(recvbuf, "Hello");
298
299 r.base = (void *) recvbuf;
300 r.length = BUFSIZ;
301 completion_init(&completion);
302 result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
303 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
304 waitfor(&completion);
305 ATF_CHECK(completion.done);
306 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
307 ATF_CHECK_STREQ(recvbuf, "World");
308
309 isc_task_detach(&task);
310
311 isc_socket_detach(&s1);
312 isc_socket_detach(&s2);
313 isc_socket_detach(&s3);
314
315 isc_test_end();
316 }
317
318 /* Test TCP sendto/recv (IPv4) */
319 ATF_TC(udp_dscp_v4);
ATF_TC_HEAD(udp_dscp_v4,tc)320 ATF_TC_HEAD(udp_dscp_v4, tc) {
321 atf_tc_set_md_var(tc, "descr", "UDP DSCP IPV4");
322 }
ATF_TC_BODY(udp_dscp_v4,tc)323 ATF_TC_BODY(udp_dscp_v4, tc) {
324 isc_result_t result;
325 isc_sockaddr_t addr1, addr2;
326 struct in_addr in;
327 isc_socket_t *s1 = NULL, *s2 = NULL;
328 isc_task_t *task = NULL;
329 char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
330 completion_t completion;
331 isc_region_t r;
332 isc_socketevent_t *socketevent;
333
334 UNUSED(tc);
335
336 result = isc_test_begin(NULL, ISC_TRUE);
337 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
338
339 /*
340 * Create two sockets: 127.0.0.1/5444 and 127.0.0.1/5445, talking to
341 * each other.
342 */
343 in.s_addr = inet_addr("127.0.0.1");
344 isc_sockaddr_fromin(&addr1, &in, 5444);
345 isc_sockaddr_fromin(&addr2, &in, 5445);
346
347 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s1);
348 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
349 isc_result_totext(result));
350 result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
351 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
352 isc_result_totext(result));
353
354 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
355 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
356 isc_result_totext(result));
357 result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
358 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
359 isc_result_totext(result));
360
361 result = isc_task_create(taskmgr, 0, &task);
362 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
363 isc_result_totext(result));
364
365 strcpy(sendbuf, "Hello");
366 r.base = (void *) sendbuf;
367 r.length = strlen(sendbuf) + 1;
368
369 completion_init(&completion);
370
371 socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE,
372 event_done, &completion);
373 ATF_REQUIRE(socketevent != NULL);
374
375 if ((isc_net_probedscp() & ISC_NET_DSCPPKTV4) != 0) {
376 socketevent->dscp = 056; /* EF */
377 socketevent->attributes |= ISC_SOCKEVENTATTR_DSCP;
378 } else if ((isc_net_probedscp() & ISC_NET_DSCPSETV4) != 0) {
379 isc_socket_dscp(s1, 056); /* EF */
380 socketevent->dscp = 0;
381 socketevent->attributes &= ~ISC_SOCKEVENTATTR_DSCP;
382 }
383
384 recv_dscp = ISC_FALSE;
385 recv_dscp_value = 0;
386
387 result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0);
388 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
389 isc_result_totext(result));
390 waitfor(&completion);
391 ATF_CHECK(completion.done);
392 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
393
394 r.base = (void *) recvbuf;
395 r.length = BUFSIZ;
396 completion_init(&completion);
397 result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
398 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
399 waitfor(&completion);
400 ATF_CHECK(completion.done);
401 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
402 ATF_CHECK_STREQ(recvbuf, "Hello");
403
404 if ((isc_net_probedscp() & ISC_NET_DSCPRECVV4) != 0) {
405 ATF_CHECK(recv_dscp);
406 ATF_CHECK_EQ(recv_dscp_value, 056);
407 } else
408 ATF_CHECK(!recv_dscp);
409 isc_task_detach(&task);
410
411 isc_socket_detach(&s1);
412 isc_socket_detach(&s2);
413
414 isc_test_end();
415 }
416
417 /* Test TCP sendto/recv (IPv4) */
418 ATF_TC(udp_dscp_v6);
ATF_TC_HEAD(udp_dscp_v6,tc)419 ATF_TC_HEAD(udp_dscp_v6, tc) {
420 atf_tc_set_md_var(tc, "descr", "udp dscp ipv6");
421 }
ATF_TC_BODY(udp_dscp_v6,tc)422 ATF_TC_BODY(udp_dscp_v6, tc) {
423 isc_result_t result;
424 isc_sockaddr_t addr1, addr2;
425 struct in6_addr in6;
426 isc_socket_t *s1 = NULL, *s2 = NULL;
427 isc_task_t *task = NULL;
428 char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
429 completion_t completion;
430 isc_region_t r;
431 isc_socketevent_t *socketevent;
432 int n;
433
434 UNUSED(tc);
435
436 result = isc_test_begin(NULL, ISC_TRUE);
437 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
438
439 /*
440 * Create two sockets: ::1/5444 and ::1/5445, talking to
441 * each other.
442 */
443 n = inet_pton(AF_INET6, "::1", &in6.s6_addr);
444 ATF_REQUIRE(n == 1);
445 isc_sockaddr_fromin6(&addr1, &in6, 5444);
446 isc_sockaddr_fromin6(&addr2, &in6, 5445);
447
448 result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_udp,
449 &s1);
450 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
451 isc_result_totext(result));
452 result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
453 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
454 isc_result_totext(result));
455
456 result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_udp,
457 &s2);
458 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
459 isc_result_totext(result));
460 result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
461 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
462 isc_result_totext(result));
463
464 result = isc_task_create(taskmgr, 0, &task);
465 ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS, "%s",
466 isc_result_totext(result));
467
468 strcpy(sendbuf, "Hello");
469 r.base = (void *) sendbuf;
470 r.length = strlen(sendbuf) + 1;
471
472 completion_init(&completion);
473
474 socketevent = isc_socket_socketevent(mctx, s1, ISC_SOCKEVENT_SENDDONE,
475 event_done, &completion);
476 ATF_REQUIRE(socketevent != NULL);
477
478 if ((isc_net_probedscp() & ISC_NET_DSCPPKTV6) != 0) {
479 socketevent->dscp = 056; /* EF */
480 socketevent->attributes = ISC_SOCKEVENTATTR_DSCP;
481 } else if ((isc_net_probedscp() & ISC_NET_DSCPSETV6) != 0)
482 isc_socket_dscp(s1, 056); /* EF */
483
484 recv_dscp = ISC_FALSE;
485 recv_dscp_value = 0;
486
487 result = isc_socket_sendto2(s1, &r, task, &addr2, NULL, socketevent, 0);
488 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
489 waitfor(&completion);
490 ATF_CHECK(completion.done);
491 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
492
493 r.base = (void *) recvbuf;
494 r.length = BUFSIZ;
495 completion_init(&completion);
496 result = isc_socket_recv(s2, &r, 1, task, event_done, &completion);
497 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
498 waitfor(&completion);
499 ATF_CHECK(completion.done);
500 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
501 ATF_CHECK_STREQ(recvbuf, "Hello");
502 if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) {
503 ATF_CHECK(recv_dscp);
504 ATF_CHECK_EQ(recv_dscp_value, 056);
505 } else
506 ATF_CHECK(!recv_dscp);
507
508 isc_task_detach(&task);
509
510 isc_socket_detach(&s1);
511 isc_socket_detach(&s2);
512
513 isc_test_end();
514 }
515
516 /* Test TCP sendto/recv (IPv4) */
517 ATF_TC(tcp_dscp_v4);
ATF_TC_HEAD(tcp_dscp_v4,tc)518 ATF_TC_HEAD(tcp_dscp_v4, tc) {
519 atf_tc_set_md_var(tc, "descr", "tcp dscp ipv4");
520 }
ATF_TC_BODY(tcp_dscp_v4,tc)521 ATF_TC_BODY(tcp_dscp_v4, tc) {
522 isc_result_t result;
523 isc_sockaddr_t addr1;
524 struct in_addr in;
525 isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
526 isc_task_t *task = NULL;
527 char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
528 completion_t completion, completion2;
529 isc_region_t r;
530
531 UNUSED(tc);
532
533 result = isc_test_begin(NULL, ISC_TRUE);
534 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
535
536 /*
537 * Create two sockets: 127.0.0.1/5444, talking to each other.
538 */
539 in.s_addr = inet_addr("127.0.0.1");
540 isc_sockaddr_fromin(&addr1, &in, 5444);
541
542 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s1);
543 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
544
545 result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
546 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
547
548 result = isc_socket_listen(s1, 3);
549 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
550
551 result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_tcp, &s2);
552 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
553
554 result = isc_task_create(taskmgr, 0, &task);
555 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
556
557 completion_init(&completion2);
558 result = isc_socket_accept(s1, task, accept_done, &completion2);
559 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
560
561 completion_init(&completion);
562 result = isc_socket_connect(s2, &addr1, task, event_done, &completion);
563 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
564 waitfor2(&completion, &completion2);
565 ATF_CHECK(completion.done);
566 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
567 ATF_CHECK(completion2.done);
568 ATF_CHECK_EQ(completion2.result, ISC_R_SUCCESS);
569 s3 = completion2.socket;
570
571 isc_socket_dscp(s2, 056); /* EF */
572
573 strcpy(sendbuf, "Hello");
574 r.base = (void *) sendbuf;
575 r.length = strlen(sendbuf) + 1;
576
577 recv_dscp = ISC_FALSE;
578 recv_dscp_value = 0;
579
580 completion_init(&completion);
581 result = isc_socket_sendto(s2, &r, task, event_done, &completion,
582 NULL, NULL);
583 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
584 waitfor(&completion);
585 ATF_CHECK(completion.done);
586 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
587
588 r.base = (void *) recvbuf;
589 r.length = BUFSIZ;
590 completion_init(&completion);
591 result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
592 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
593 waitfor(&completion);
594 ATF_CHECK(completion.done);
595 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
596 ATF_CHECK_STREQ(recvbuf, "Hello");
597
598 if ((isc_net_probedscp() & ISC_NET_DSCPRECVV4) != 0) {
599 if (recv_dscp)
600 ATF_CHECK_EQ(recv_dscp_value, 056);
601 } else
602 ATF_CHECK(!recv_dscp);
603
604 isc_task_detach(&task);
605
606 isc_socket_detach(&s1);
607 isc_socket_detach(&s2);
608 isc_socket_detach(&s3);
609
610 isc_test_end();
611 }
612
613 /* Test TCP sendto/recv (IPv6) */
614 ATF_TC(tcp_dscp_v6);
ATF_TC_HEAD(tcp_dscp_v6,tc)615 ATF_TC_HEAD(tcp_dscp_v6, tc) {
616 atf_tc_set_md_var(tc, "descr", "tcp dscp ipv6");
617 }
ATF_TC_BODY(tcp_dscp_v6,tc)618 ATF_TC_BODY(tcp_dscp_v6, tc) {
619 isc_result_t result;
620 isc_sockaddr_t addr1;
621 struct in6_addr in6;
622 isc_socket_t *s1 = NULL, *s2 = NULL, *s3 = NULL;
623 isc_task_t *task = NULL;
624 char sendbuf[BUFSIZ], recvbuf[BUFSIZ];
625 completion_t completion, completion2;
626 isc_region_t r;
627 int n;
628
629 UNUSED(tc);
630
631 result = isc_test_begin(NULL, ISC_TRUE);
632 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
633
634 /*
635 * Create two sockets: ::1/5444, talking to each other.
636 */
637 n = inet_pton(AF_INET6, "::1", &in6.s6_addr);
638 ATF_REQUIRE(n == 1);
639 isc_sockaddr_fromin6(&addr1, &in6, 5444);
640
641 result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_tcp,
642 &s1);
643 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
644
645 result = isc_socket_bind(s1, &addr1, ISC_SOCKET_REUSEADDRESS);
646 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
647
648 result = isc_socket_listen(s1, 3);
649 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
650
651 result = isc_socket_create(socketmgr, PF_INET6, isc_sockettype_tcp,
652 &s2);
653 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
654
655 result = isc_task_create(taskmgr, 0, &task);
656 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
657
658 completion_init(&completion2);
659 result = isc_socket_accept(s1, task, accept_done, &completion2);
660 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
661
662 completion_init(&completion);
663 result = isc_socket_connect(s2, &addr1, task, event_done, &completion);
664 ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
665 waitfor2(&completion, &completion2);
666 ATF_CHECK(completion.done);
667 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
668 ATF_CHECK(completion2.done);
669 ATF_CHECK_EQ(completion2.result, ISC_R_SUCCESS);
670 s3 = completion2.socket;
671
672 isc_socket_dscp(s2, 056); /* EF */
673
674 strcpy(sendbuf, "Hello");
675 r.base = (void *) sendbuf;
676 r.length = strlen(sendbuf) + 1;
677
678 recv_dscp = ISC_FALSE;
679 recv_dscp_value = 0;
680
681 completion_init(&completion);
682 result = isc_socket_sendto(s2, &r, task, event_done, &completion,
683 NULL, NULL);
684 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
685 waitfor(&completion);
686 ATF_CHECK(completion.done);
687 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
688
689 r.base = (void *) recvbuf;
690 r.length = BUFSIZ;
691 completion_init(&completion);
692 result = isc_socket_recv(s3, &r, 1, task, event_done, &completion);
693 ATF_CHECK_EQ(result, ISC_R_SUCCESS);
694 waitfor(&completion);
695 ATF_CHECK(completion.done);
696 ATF_CHECK_EQ(completion.result, ISC_R_SUCCESS);
697 ATF_CHECK_STREQ(recvbuf, "Hello");
698
699 if ((isc_net_probedscp() & ISC_NET_DSCPRECVV6) != 0) {
700 /*
701 * IPV6_RECVTCLASS is undefined for TCP however
702 * if we do get it should be the the value we set.
703 */
704 if (recv_dscp)
705 ATF_CHECK_EQ(recv_dscp_value, 056);
706 } else
707 ATF_CHECK(!recv_dscp);
708
709 isc_task_detach(&task);
710
711 isc_socket_detach(&s1);
712 isc_socket_detach(&s2);
713 isc_socket_detach(&s3);
714
715 isc_test_end();
716 }
717
718 ATF_TC(net_probedscp);
ATF_TC_HEAD(net_probedscp,tc)719 ATF_TC_HEAD(net_probedscp, tc) {
720 atf_tc_set_md_var(tc, "descr", "probe dscp capabilities");
721 }
ATF_TC_BODY(net_probedscp,tc)722 ATF_TC_BODY(net_probedscp, tc) {
723 unsigned int n;
724
725 UNUSED(tc);
726
727 n = isc_net_probedscp();
728 ATF_CHECK((n & ~ISC_NET_DSCPALL) == 0);
729
730 /* ISC_NET_DSCPSETV4 MUST be set if any is set. */
731 if (n & (ISC_NET_DSCPSETV4|ISC_NET_DSCPPKTV4|ISC_NET_DSCPRECVV4))
732 ATF_CHECK_MSG((n & ISC_NET_DSCPSETV4) != 0,
733 "IPv4:%s%s%s\n",
734 (n & ISC_NET_DSCPSETV4) ? " set" : " none",
735 (n & ISC_NET_DSCPPKTV4) ? " packet" : "",
736 (n & ISC_NET_DSCPRECVV4) ? " receive" : "");
737
738 /* ISC_NET_DSCPSETV6 MUST be set if any is set. */
739 if (n & (ISC_NET_DSCPSETV6|ISC_NET_DSCPPKTV4|ISC_NET_DSCPRECVV4))
740 ATF_CHECK_MSG((n & ISC_NET_DSCPSETV6) != 0,
741 "IPv6:%s%s%s\n",
742 (n & ISC_NET_DSCPSETV6) ? " set" : " none",
743 (n & ISC_NET_DSCPPKTV6) ? " packet" : "",
744 (n & ISC_NET_DSCPRECVV6) ? " receive" : "");
745
746 #if 0
747 fprintf(stdout, "IPv4:%s%s%s\n",
748 (n & ISC_NET_DSCPSETV4) ? " set" : "none",
749 (n & ISC_NET_DSCPPKTV4) ? " packet" : "",
750 (n & ISC_NET_DSCPRECVV4) ? " receive" : "");
751
752 fprintf(stdout, "IPv6:%s%s%s\n",
753 (n & ISC_NET_DSCPSETV6) ? " set" : "none",
754 (n & ISC_NET_DSCPPKTV6) ? " packet" : "",
755 (n & ISC_NET_DSCPRECVV6) ? " receive" : "");
756 #endif
757 }
758
759 /*
760 * Main
761 */
ATF_TP_ADD_TCS(tp)762 ATF_TP_ADD_TCS(tp) {
763 ATF_TP_ADD_TC(tp, udp_sendto);
764 ATF_TP_ADD_TC(tp, udp_dup);
765 ATF_TP_ADD_TC(tp, tcp_dscp_v4);
766 ATF_TP_ADD_TC(tp, tcp_dscp_v6);
767 ATF_TP_ADD_TC(tp, udp_dscp_v4);
768 ATF_TP_ADD_TC(tp, udp_dscp_v6);
769 ATF_TP_ADD_TC(tp, net_probedscp);
770
771 return (atf_no_error());
772 }
773