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 50 completion_init(completion_t *completion) { 51 completion->done = ISC_FALSE; 52 completion->socket = NULL; 53 } 54 55 static void 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 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 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 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 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); 152 ATF_TC_HEAD(udp_sendto, tc) { 153 atf_tc_set_md_var(tc, "descr", "UDP sendto/recv"); 154 } 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); 223 ATF_TC_HEAD(udp_dup, tc) { 224 atf_tc_set_md_var(tc, "descr", "duplicated socket sendto/recv"); 225 } 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); 320 ATF_TC_HEAD(udp_dscp_v4, tc) { 321 atf_tc_set_md_var(tc, "descr", "UDP DSCP IPV4"); 322 } 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); 419 ATF_TC_HEAD(udp_dscp_v6, tc) { 420 atf_tc_set_md_var(tc, "descr", "udp dscp ipv6"); 421 } 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); 518 ATF_TC_HEAD(tcp_dscp_v4, tc) { 519 atf_tc_set_md_var(tc, "descr", "tcp dscp ipv4"); 520 } 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); 615 ATF_TC_HEAD(tcp_dscp_v6, tc) { 616 atf_tc_set_md_var(tc, "descr", "tcp dscp ipv6"); 617 } 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); 719 ATF_TC_HEAD(net_probedscp, tc) { 720 atf_tc_set_md_var(tc, "descr", "probe dscp capabilities"); 721 } 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 */ 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