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