1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 */ 21 22 #include <assert.h> 23 #include <stdlib.h> 24 25 #include "uv.h" 26 #include "internal.h" 27 #include "handle-inl.h" 28 #include "stream-inl.h" 29 #include "req-inl.h" 30 31 32 /* A zero-size buffer for use by uv_udp_read */ 33 static char uv_zero_[] = ""; 34 int uv_udp_getpeername(const uv_udp_t* handle, 35 struct sockaddr* name, 36 int* namelen) { 37 38 return uv__getsockpeername((const uv_handle_t*) handle, 39 getpeername, 40 name, 41 namelen, 42 0); 43 } 44 45 46 int uv_udp_getsockname(const uv_udp_t* handle, 47 struct sockaddr* name, 48 int* namelen) { 49 50 return uv__getsockpeername((const uv_handle_t*) handle, 51 getsockname, 52 name, 53 namelen, 54 0); 55 } 56 57 58 static int uv__udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket, 59 int family) { 60 DWORD yes = 1; 61 WSAPROTOCOL_INFOW info; 62 int opt_len; 63 64 if (handle->socket != INVALID_SOCKET) 65 return UV_EBUSY; 66 67 /* Set the socket to nonblocking mode */ 68 if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { 69 return WSAGetLastError(); 70 } 71 72 /* Make the socket non-inheritable */ 73 if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { 74 return GetLastError(); 75 } 76 77 /* Associate it with the I/O completion port. Use uv_handle_t pointer as 78 * completion key. */ 79 if (CreateIoCompletionPort((HANDLE)socket, 80 loop->iocp, 81 (ULONG_PTR)socket, 82 0) == NULL) { 83 return GetLastError(); 84 } 85 86 /* All known Windows that support SetFileCompletionNotificationModes have a 87 * bug that makes it impossible to use this function in conjunction with 88 * datagram sockets. We can work around that but only if the user is using 89 * the default UDP driver (AFD) and has no other. LSPs stacked on top. Here 90 * we check whether that is the case. */ 91 opt_len = (int) sizeof info; 92 if (getsockopt( 93 socket, SOL_SOCKET, SO_PROTOCOL_INFOW, (char*) &info, &opt_len) == 94 SOCKET_ERROR) { 95 return GetLastError(); 96 } 97 98 if (info.ProtocolChain.ChainLen == 1) { 99 if (SetFileCompletionNotificationModes( 100 (HANDLE) socket, 101 FILE_SKIP_SET_EVENT_ON_HANDLE | 102 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { 103 handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; 104 handle->func_wsarecv = uv__wsarecv_workaround; 105 handle->func_wsarecvfrom = uv__wsarecvfrom_workaround; 106 } else if (GetLastError() != ERROR_INVALID_FUNCTION) { 107 return GetLastError(); 108 } 109 } 110 111 handle->socket = socket; 112 113 if (family == AF_INET6) { 114 handle->flags |= UV_HANDLE_IPV6; 115 } else { 116 assert(!(handle->flags & UV_HANDLE_IPV6)); 117 } 118 119 return 0; 120 } 121 122 123 int uv__udp_init_ex(uv_loop_t* loop, 124 uv_udp_t* handle, 125 unsigned flags, 126 int domain) { 127 uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP); 128 handle->socket = INVALID_SOCKET; 129 handle->reqs_pending = 0; 130 handle->activecnt = 0; 131 handle->func_wsarecv = WSARecv; 132 handle->func_wsarecvfrom = WSARecvFrom; 133 handle->send_queue_size = 0; 134 handle->send_queue_count = 0; 135 UV_REQ_INIT(&handle->recv_req, UV_UDP_RECV); 136 handle->recv_req.data = handle; 137 138 /* If anything fails beyond this point we need to remove the handle from 139 * the handle queue, since it was added by uv__handle_init. 140 */ 141 142 if (domain != AF_UNSPEC) { 143 SOCKET sock; 144 DWORD err; 145 146 sock = socket(domain, SOCK_DGRAM, 0); 147 if (sock == INVALID_SOCKET) { 148 err = WSAGetLastError(); 149 uv__queue_remove(&handle->handle_queue); 150 return uv_translate_sys_error(err); 151 } 152 153 err = uv__udp_set_socket(handle->loop, handle, sock, domain); 154 if (err) { 155 closesocket(sock); 156 uv__queue_remove(&handle->handle_queue); 157 return uv_translate_sys_error(err); 158 } 159 } 160 161 return 0; 162 } 163 164 165 void uv__udp_close(uv_loop_t* loop, uv_udp_t* handle) { 166 uv_udp_recv_stop(handle); 167 closesocket(handle->socket); 168 handle->socket = INVALID_SOCKET; 169 170 uv__handle_closing(handle); 171 172 if (handle->reqs_pending == 0) { 173 uv__want_endgame(loop, (uv_handle_t*) handle); 174 } 175 } 176 177 178 void uv__udp_endgame(uv_loop_t* loop, uv_udp_t* handle) { 179 if (handle->flags & UV_HANDLE_CLOSING && 180 handle->reqs_pending == 0) { 181 assert(!(handle->flags & UV_HANDLE_CLOSED)); 182 uv__handle_close(handle); 183 } 184 } 185 186 187 int uv_udp_using_recvmmsg(const uv_udp_t* handle) { 188 return 0; 189 } 190 191 192 static int uv__udp_maybe_bind(uv_udp_t* handle, 193 const struct sockaddr* addr, 194 unsigned int addrlen, 195 unsigned int flags) { 196 int r; 197 int err; 198 DWORD no = 0; 199 200 if (handle->flags & UV_HANDLE_BOUND) 201 return 0; 202 203 /* There is no SO_REUSEPORT on Windows, Windows only knows SO_REUSEADDR. 204 * so we just return an error directly when UV_UDP_REUSEPORT is requested 205 * for binding the socket. */ 206 if (flags & UV_UDP_REUSEPORT) 207 return ERROR_NOT_SUPPORTED; 208 209 if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) { 210 /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */ 211 return ERROR_INVALID_PARAMETER; 212 } 213 214 if (handle->socket == INVALID_SOCKET) { 215 SOCKET sock = socket(addr->sa_family, SOCK_DGRAM, 0); 216 if (sock == INVALID_SOCKET) { 217 return WSAGetLastError(); 218 } 219 220 err = uv__udp_set_socket(handle->loop, handle, sock, addr->sa_family); 221 if (err) { 222 closesocket(sock); 223 return err; 224 } 225 } 226 227 if (flags & UV_UDP_REUSEADDR) { 228 DWORD yes = 1; 229 /* Set SO_REUSEADDR on the socket. */ 230 if (setsockopt(handle->socket, 231 SOL_SOCKET, 232 SO_REUSEADDR, 233 (char*) &yes, 234 sizeof yes) == SOCKET_ERROR) { 235 err = WSAGetLastError(); 236 return err; 237 } 238 } 239 240 if (addr->sa_family == AF_INET6) 241 handle->flags |= UV_HANDLE_IPV6; 242 243 if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) { 244 /* On windows IPV6ONLY is on by default. If the user doesn't specify it 245 * libuv turns it off. */ 246 247 /* TODO: how to handle errors? This may fail if there is no ipv4 stack 248 * available, or when run on XP/2003 which have no support for dualstack 249 * sockets. For now we're silently ignoring the error. */ 250 setsockopt(handle->socket, 251 IPPROTO_IPV6, 252 IPV6_V6ONLY, 253 (char*) &no, 254 sizeof no); 255 } 256 257 r = bind(handle->socket, addr, addrlen); 258 if (r == SOCKET_ERROR) { 259 return WSAGetLastError(); 260 } 261 262 handle->flags |= UV_HANDLE_BOUND; 263 264 return 0; 265 } 266 267 268 static void uv__udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { 269 uv_req_t* req; 270 uv_buf_t buf; 271 DWORD bytes, flags; 272 int result; 273 274 assert(handle->flags & UV_HANDLE_READING); 275 assert(!(handle->flags & UV_HANDLE_READ_PENDING)); 276 277 req = &handle->recv_req; 278 memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); 279 280 handle->flags |= UV_HANDLE_ZERO_READ; 281 282 buf.base = (char*) uv_zero_; 283 buf.len = 0; 284 flags = MSG_PEEK; 285 286 result = handle->func_wsarecv(handle->socket, 287 (WSABUF*) &buf, 288 1, 289 &bytes, 290 &flags, 291 &req->u.io.overlapped, 292 NULL); 293 294 if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { 295 /* Process the req without IOCP. */ 296 handle->flags |= UV_HANDLE_READ_PENDING; 297 req->u.io.overlapped.InternalHigh = bytes; 298 handle->reqs_pending++; 299 uv__insert_pending_req(loop, req); 300 } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { 301 /* The req will be processed with IOCP. */ 302 handle->flags |= UV_HANDLE_READ_PENDING; 303 handle->reqs_pending++; 304 } else { 305 /* Make this req pending reporting an error. */ 306 SET_REQ_ERROR(req, WSAGetLastError()); 307 uv__insert_pending_req(loop, req); 308 handle->reqs_pending++; 309 } 310 } 311 312 313 int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, 314 uv_udp_recv_cb recv_cb) { 315 uv_loop_t* loop = handle->loop; 316 int err; 317 318 if (handle->flags & UV_HANDLE_READING) { 319 return UV_EALREADY; 320 } 321 322 err = uv__udp_maybe_bind(handle, 323 (const struct sockaddr*) &uv_addr_ip4_any_, 324 sizeof(uv_addr_ip4_any_), 325 0); 326 if (err) 327 return uv_translate_sys_error(err); 328 329 handle->flags |= UV_HANDLE_READING; 330 INCREASE_ACTIVE_COUNT(loop, handle); 331 332 handle->recv_cb = recv_cb; 333 handle->alloc_cb = alloc_cb; 334 335 /* If reading was stopped and then started again, there could still be a recv 336 * request pending. */ 337 if (!(handle->flags & UV_HANDLE_READ_PENDING)) 338 uv__udp_queue_recv(loop, handle); 339 340 return 0; 341 } 342 343 344 int uv__udp_recv_stop(uv_udp_t* handle) { 345 if (handle->flags & UV_HANDLE_READING) { 346 handle->flags &= ~UV_HANDLE_READING; 347 DECREASE_ACTIVE_COUNT(loop, handle); 348 } 349 350 return 0; 351 } 352 353 354 static int uv__send(uv_udp_send_t* req, 355 uv_udp_t* handle, 356 const uv_buf_t bufs[], 357 unsigned int nbufs, 358 const struct sockaddr* addr, 359 unsigned int addrlen, 360 uv_udp_send_cb cb) { 361 uv_loop_t* loop = handle->loop; 362 DWORD result, bytes; 363 364 UV_REQ_INIT(req, UV_UDP_SEND); 365 req->handle = handle; 366 req->cb = cb; 367 memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); 368 369 result = WSASendTo(handle->socket, 370 (WSABUF*)bufs, 371 nbufs, 372 &bytes, 373 0, 374 addr, 375 addrlen, 376 &req->u.io.overlapped, 377 NULL); 378 379 if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { 380 /* Request completed immediately. */ 381 req->u.io.queued_bytes = 0; 382 handle->reqs_pending++; 383 handle->send_queue_size += req->u.io.queued_bytes; 384 handle->send_queue_count++; 385 REGISTER_HANDLE_REQ(loop, handle); 386 uv__insert_pending_req(loop, (uv_req_t*)req); 387 } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { 388 /* Request queued by the kernel. */ 389 req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); 390 handle->reqs_pending++; 391 handle->send_queue_size += req->u.io.queued_bytes; 392 handle->send_queue_count++; 393 REGISTER_HANDLE_REQ(loop, handle); 394 } else { 395 /* Send failed due to an error. */ 396 return WSAGetLastError(); 397 } 398 399 return 0; 400 } 401 402 403 void uv__process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, 404 uv_req_t* req) { 405 uv_buf_t buf; 406 int partial; 407 408 assert(handle->type == UV_UDP); 409 410 handle->flags &= ~UV_HANDLE_READ_PENDING; 411 412 if (!REQ_SUCCESS(req)) { 413 DWORD err = GET_REQ_SOCK_ERROR(req); 414 if (err == WSAEMSGSIZE) { 415 /* Not a real error, it just indicates that the received packet was 416 * bigger than the receive buffer. */ 417 } else if (err == WSAECONNRESET || err == WSAENETRESET) { 418 /* A previous sendto operation failed; ignore this error. If zero-reading 419 * we need to call WSARecv/WSARecvFrom _without_ the. MSG_PEEK flag to 420 * clear out the error queue. For nonzero reads, immediately queue a new 421 * receive. */ 422 if (!(handle->flags & UV_HANDLE_ZERO_READ)) { 423 goto done; 424 } 425 } else { 426 /* A real error occurred. Report the error to the user only if we're 427 * currently reading. */ 428 if (handle->flags & UV_HANDLE_READING) { 429 uv_udp_recv_stop(handle); 430 buf = (handle->flags & UV_HANDLE_ZERO_READ) ? 431 uv_buf_init(NULL, 0) : handle->recv_buffer; 432 handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); 433 } 434 goto done; 435 } 436 } 437 438 if (!(handle->flags & UV_HANDLE_ZERO_READ)) { 439 /* Successful read */ 440 partial = !REQ_SUCCESS(req); 441 handle->recv_cb(handle, 442 req->u.io.overlapped.InternalHigh, 443 &handle->recv_buffer, 444 (const struct sockaddr*) &handle->recv_from, 445 partial ? UV_UDP_PARTIAL : 0); 446 } else if (handle->flags & UV_HANDLE_READING) { 447 DWORD bytes, err, flags; 448 struct sockaddr_storage from; 449 int from_len; 450 int count; 451 452 /* Prevent loop starvation when the data comes in as fast as 453 * (or faster than) we can read it. */ 454 count = 32; 455 456 do { 457 /* Do at most `count` nonblocking receive. */ 458 buf = uv_buf_init(NULL, 0); 459 handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf); 460 if (buf.base == NULL || buf.len == 0) { 461 handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); 462 goto done; 463 } 464 465 memset(&from, 0, sizeof from); 466 from_len = sizeof from; 467 468 flags = 0; 469 470 if (WSARecvFrom(handle->socket, 471 (WSABUF*)&buf, 472 1, 473 &bytes, 474 &flags, 475 (struct sockaddr*) &from, 476 &from_len, 477 NULL, 478 NULL) != SOCKET_ERROR) { 479 480 /* Message received */ 481 err = ERROR_SUCCESS; 482 handle->recv_cb(handle, bytes, &buf, (const struct sockaddr*) &from, 0); 483 } else { 484 err = WSAGetLastError(); 485 if (err == WSAEMSGSIZE) { 486 /* Message truncated */ 487 handle->recv_cb(handle, 488 bytes, 489 &buf, 490 (const struct sockaddr*) &from, 491 UV_UDP_PARTIAL); 492 } else if (err == WSAEWOULDBLOCK) { 493 /* Kernel buffer empty */ 494 handle->recv_cb(handle, 0, &buf, NULL, 0); 495 } else if (err == WSAECONNRESET || err == WSAENETRESET) { 496 /* WSAECONNRESET/WSANETRESET is ignored because this just indicates 497 * that a previous sendto operation failed. 498 */ 499 handle->recv_cb(handle, 0, &buf, NULL, 0); 500 } else { 501 /* Any other error that we want to report back to the user. */ 502 uv_udp_recv_stop(handle); 503 handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); 504 } 505 } 506 } 507 while (err == ERROR_SUCCESS && 508 count-- > 0 && 509 /* The recv_cb callback may decide to pause or close the handle. */ 510 (handle->flags & UV_HANDLE_READING) && 511 !(handle->flags & UV_HANDLE_READ_PENDING)); 512 } 513 514 done: 515 /* Post another read if still reading and not closing. */ 516 if ((handle->flags & UV_HANDLE_READING) && 517 !(handle->flags & UV_HANDLE_READ_PENDING)) { 518 uv__udp_queue_recv(loop, handle); 519 } 520 521 DECREASE_PENDING_REQ_COUNT(handle); 522 } 523 524 525 void uv__process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, 526 uv_udp_send_t* req) { 527 int err; 528 529 assert(handle->type == UV_UDP); 530 531 assert(handle->send_queue_size >= req->u.io.queued_bytes); 532 assert(handle->send_queue_count >= 1); 533 handle->send_queue_size -= req->u.io.queued_bytes; 534 handle->send_queue_count--; 535 536 UNREGISTER_HANDLE_REQ(loop, handle); 537 538 if (req->cb) { 539 err = 0; 540 if (!REQ_SUCCESS(req)) { 541 err = GET_REQ_SOCK_ERROR(req); 542 } 543 req->cb(req, uv_translate_sys_error(err)); 544 } 545 546 DECREASE_PENDING_REQ_COUNT(handle); 547 } 548 549 550 static int uv__udp_set_membership4(uv_udp_t* handle, 551 const struct sockaddr_in* multicast_addr, 552 const char* interface_addr, 553 uv_membership membership) { 554 int err; 555 int optname; 556 struct ip_mreq mreq; 557 558 if (handle->flags & UV_HANDLE_IPV6) 559 return UV_EINVAL; 560 561 /* If the socket is unbound, bind to inaddr_any. */ 562 err = uv__udp_maybe_bind(handle, 563 (const struct sockaddr*) &uv_addr_ip4_any_, 564 sizeof(uv_addr_ip4_any_), 565 UV_UDP_REUSEADDR); 566 if (err) 567 return uv_translate_sys_error(err); 568 569 memset(&mreq, 0, sizeof mreq); 570 571 if (interface_addr) { 572 err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); 573 if (err) 574 return err; 575 } else { 576 mreq.imr_interface.s_addr = htonl(INADDR_ANY); 577 } 578 579 mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; 580 581 switch (membership) { 582 case UV_JOIN_GROUP: 583 optname = IP_ADD_MEMBERSHIP; 584 break; 585 case UV_LEAVE_GROUP: 586 optname = IP_DROP_MEMBERSHIP; 587 break; 588 default: 589 return UV_EINVAL; 590 } 591 592 if (setsockopt(handle->socket, 593 IPPROTO_IP, 594 optname, 595 (char*) &mreq, 596 sizeof mreq) == SOCKET_ERROR) { 597 return uv_translate_sys_error(WSAGetLastError()); 598 } 599 600 return 0; 601 } 602 603 604 int uv__udp_set_membership6(uv_udp_t* handle, 605 const struct sockaddr_in6* multicast_addr, 606 const char* interface_addr, 607 uv_membership membership) { 608 int optname; 609 int err; 610 struct ipv6_mreq mreq; 611 struct sockaddr_in6 addr6; 612 613 if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6)) 614 return UV_EINVAL; 615 616 err = uv__udp_maybe_bind(handle, 617 (const struct sockaddr*) &uv_addr_ip6_any_, 618 sizeof(uv_addr_ip6_any_), 619 UV_UDP_REUSEADDR); 620 621 if (err) 622 return uv_translate_sys_error(err); 623 624 memset(&mreq, 0, sizeof(mreq)); 625 626 if (interface_addr) { 627 if (uv_ip6_addr(interface_addr, 0, &addr6)) 628 return UV_EINVAL; 629 mreq.ipv6mr_interface = addr6.sin6_scope_id; 630 } else { 631 mreq.ipv6mr_interface = 0; 632 } 633 634 mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr; 635 636 switch (membership) { 637 case UV_JOIN_GROUP: 638 optname = IPV6_ADD_MEMBERSHIP; 639 break; 640 case UV_LEAVE_GROUP: 641 optname = IPV6_DROP_MEMBERSHIP; 642 break; 643 default: 644 return UV_EINVAL; 645 } 646 647 if (setsockopt(handle->socket, 648 IPPROTO_IPV6, 649 optname, 650 (char*) &mreq, 651 sizeof mreq) == SOCKET_ERROR) { 652 return uv_translate_sys_error(WSAGetLastError()); 653 } 654 655 return 0; 656 } 657 658 659 static int uv__udp_set_source_membership4(uv_udp_t* handle, 660 const struct sockaddr_in* multicast_addr, 661 const char* interface_addr, 662 const struct sockaddr_in* source_addr, 663 uv_membership membership) { 664 struct ip_mreq_source mreq; 665 int optname; 666 int err; 667 668 if (handle->flags & UV_HANDLE_IPV6) 669 return UV_EINVAL; 670 671 /* If the socket is unbound, bind to inaddr_any. */ 672 err = uv__udp_maybe_bind(handle, 673 (const struct sockaddr*) &uv_addr_ip4_any_, 674 sizeof(uv_addr_ip4_any_), 675 UV_UDP_REUSEADDR); 676 if (err) 677 return uv_translate_sys_error(err); 678 679 memset(&mreq, 0, sizeof(mreq)); 680 681 if (interface_addr != NULL) { 682 err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); 683 if (err) 684 return err; 685 } else { 686 mreq.imr_interface.s_addr = htonl(INADDR_ANY); 687 } 688 689 mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; 690 mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr; 691 692 if (membership == UV_JOIN_GROUP) 693 optname = IP_ADD_SOURCE_MEMBERSHIP; 694 else if (membership == UV_LEAVE_GROUP) 695 optname = IP_DROP_SOURCE_MEMBERSHIP; 696 else 697 return UV_EINVAL; 698 699 if (setsockopt(handle->socket, 700 IPPROTO_IP, 701 optname, 702 (char*) &mreq, 703 sizeof(mreq)) == SOCKET_ERROR) { 704 return uv_translate_sys_error(WSAGetLastError()); 705 } 706 707 return 0; 708 } 709 710 711 int uv__udp_set_source_membership6(uv_udp_t* handle, 712 const struct sockaddr_in6* multicast_addr, 713 const char* interface_addr, 714 const struct sockaddr_in6* source_addr, 715 uv_membership membership) { 716 struct group_source_req mreq; 717 struct sockaddr_in6 addr6; 718 int optname; 719 int err; 720 721 STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr)); 722 STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr)); 723 724 if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6)) 725 return UV_EINVAL; 726 727 err = uv__udp_maybe_bind(handle, 728 (const struct sockaddr*) &uv_addr_ip6_any_, 729 sizeof(uv_addr_ip6_any_), 730 UV_UDP_REUSEADDR); 731 732 if (err) 733 return uv_translate_sys_error(err); 734 735 memset(&mreq, 0, sizeof(mreq)); 736 737 if (interface_addr != NULL) { 738 err = uv_ip6_addr(interface_addr, 0, &addr6); 739 if (err) 740 return err; 741 mreq.gsr_interface = addr6.sin6_scope_id; 742 } else { 743 mreq.gsr_interface = 0; 744 } 745 746 memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr)); 747 memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr)); 748 749 if (membership == UV_JOIN_GROUP) 750 optname = MCAST_JOIN_SOURCE_GROUP; 751 else if (membership == UV_LEAVE_GROUP) 752 optname = MCAST_LEAVE_SOURCE_GROUP; 753 else 754 return UV_EINVAL; 755 756 if (setsockopt(handle->socket, 757 IPPROTO_IPV6, 758 optname, 759 (char*) &mreq, 760 sizeof(mreq)) == SOCKET_ERROR) { 761 return uv_translate_sys_error(WSAGetLastError()); 762 } 763 764 return 0; 765 } 766 767 768 int uv_udp_set_membership(uv_udp_t* handle, 769 const char* multicast_addr, 770 const char* interface_addr, 771 uv_membership membership) { 772 struct sockaddr_in addr4; 773 struct sockaddr_in6 addr6; 774 775 if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) 776 return uv__udp_set_membership4(handle, &addr4, interface_addr, membership); 777 else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) 778 return uv__udp_set_membership6(handle, &addr6, interface_addr, membership); 779 else 780 return UV_EINVAL; 781 } 782 783 784 int uv_udp_set_source_membership(uv_udp_t* handle, 785 const char* multicast_addr, 786 const char* interface_addr, 787 const char* source_addr, 788 uv_membership membership) { 789 int err; 790 struct sockaddr_storage mcast_addr; 791 struct sockaddr_in* mcast_addr4; 792 struct sockaddr_in6* mcast_addr6; 793 struct sockaddr_storage src_addr; 794 struct sockaddr_in* src_addr4; 795 struct sockaddr_in6* src_addr6; 796 797 mcast_addr4 = (struct sockaddr_in*)&mcast_addr; 798 mcast_addr6 = (struct sockaddr_in6*)&mcast_addr; 799 src_addr4 = (struct sockaddr_in*)&src_addr; 800 src_addr6 = (struct sockaddr_in6*)&src_addr; 801 802 err = uv_ip4_addr(multicast_addr, 0, mcast_addr4); 803 if (err) { 804 err = uv_ip6_addr(multicast_addr, 0, mcast_addr6); 805 if (err) 806 return err; 807 err = uv_ip6_addr(source_addr, 0, src_addr6); 808 if (err) 809 return err; 810 return uv__udp_set_source_membership6(handle, 811 mcast_addr6, 812 interface_addr, 813 src_addr6, 814 membership); 815 } 816 817 err = uv_ip4_addr(source_addr, 0, src_addr4); 818 if (err) 819 return err; 820 return uv__udp_set_source_membership4(handle, 821 mcast_addr4, 822 interface_addr, 823 src_addr4, 824 membership); 825 } 826 827 828 int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) { 829 struct sockaddr_storage addr_st; 830 struct sockaddr_in* addr4; 831 struct sockaddr_in6* addr6; 832 833 addr4 = (struct sockaddr_in*) &addr_st; 834 addr6 = (struct sockaddr_in6*) &addr_st; 835 836 if (!interface_addr) { 837 memset(&addr_st, 0, sizeof addr_st); 838 if (handle->flags & UV_HANDLE_IPV6) { 839 addr_st.ss_family = AF_INET6; 840 addr6->sin6_scope_id = 0; 841 } else { 842 addr_st.ss_family = AF_INET; 843 addr4->sin_addr.s_addr = htonl(INADDR_ANY); 844 } 845 } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) { 846 /* nothing, address was parsed */ 847 } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) { 848 /* nothing, address was parsed */ 849 } else { 850 return UV_EINVAL; 851 } 852 853 if (handle->socket == INVALID_SOCKET) 854 return UV_EBADF; 855 856 if (addr_st.ss_family == AF_INET) { 857 if (setsockopt(handle->socket, 858 IPPROTO_IP, 859 IP_MULTICAST_IF, 860 (char*) &addr4->sin_addr, 861 sizeof(addr4->sin_addr)) == SOCKET_ERROR) { 862 return uv_translate_sys_error(WSAGetLastError()); 863 } 864 } else if (addr_st.ss_family == AF_INET6) { 865 if (setsockopt(handle->socket, 866 IPPROTO_IPV6, 867 IPV6_MULTICAST_IF, 868 (char*) &addr6->sin6_scope_id, 869 sizeof(addr6->sin6_scope_id)) == SOCKET_ERROR) { 870 return uv_translate_sys_error(WSAGetLastError()); 871 } 872 } else { 873 assert(0 && "unexpected address family"); 874 abort(); 875 } 876 877 return 0; 878 } 879 880 881 int uv_udp_set_broadcast(uv_udp_t* handle, int value) { 882 BOOL optval = (BOOL) value; 883 884 if (handle->socket == INVALID_SOCKET) 885 return UV_EBADF; 886 887 if (setsockopt(handle->socket, 888 SOL_SOCKET, 889 SO_BROADCAST, 890 (char*) &optval, 891 sizeof optval)) { 892 return uv_translate_sys_error(WSAGetLastError()); 893 } 894 895 return 0; 896 } 897 898 899 int uv__udp_is_bound(uv_udp_t* handle) { 900 struct sockaddr_storage addr; 901 int addrlen; 902 903 addrlen = sizeof(addr); 904 if (uv_udp_getsockname(handle, (struct sockaddr*) &addr, &addrlen) != 0) 905 return 0; 906 907 return addrlen > 0; 908 } 909 910 911 int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { 912 WSAPROTOCOL_INFOW protocol_info; 913 int opt_len; 914 int err; 915 916 /* Detect the address family of the socket. */ 917 opt_len = (int) sizeof protocol_info; 918 if (getsockopt(sock, 919 SOL_SOCKET, 920 SO_PROTOCOL_INFOW, 921 (char*) &protocol_info, 922 &opt_len) == SOCKET_ERROR) { 923 return uv_translate_sys_error(GetLastError()); 924 } 925 926 err = uv__udp_set_socket(handle->loop, 927 handle, 928 sock, 929 protocol_info.iAddressFamily); 930 if (err) 931 return uv_translate_sys_error(err); 932 933 if (uv__udp_is_bound(handle)) 934 handle->flags |= UV_HANDLE_BOUND; 935 936 if (uv__udp_is_connected(handle)) 937 handle->flags |= UV_HANDLE_UDP_CONNECTED; 938 939 return 0; 940 } 941 942 943 #define SOCKOPT_SETTER(name, option4, option6, validate) \ 944 int uv_udp_set_##name(uv_udp_t* handle, int value) { \ 945 DWORD optval = (DWORD) value; \ 946 \ 947 if (!(validate(value))) { \ 948 return UV_EINVAL; \ 949 } \ 950 \ 951 if (handle->socket == INVALID_SOCKET) \ 952 return UV_EBADF; \ 953 \ 954 if (!(handle->flags & UV_HANDLE_IPV6)) { \ 955 /* Set IPv4 socket option */ \ 956 if (setsockopt(handle->socket, \ 957 IPPROTO_IP, \ 958 option4, \ 959 (char*) &optval, \ 960 sizeof optval)) { \ 961 return uv_translate_sys_error(WSAGetLastError()); \ 962 } \ 963 } else { \ 964 /* Set IPv6 socket option */ \ 965 if (setsockopt(handle->socket, \ 966 IPPROTO_IPV6, \ 967 option6, \ 968 (char*) &optval, \ 969 sizeof optval)) { \ 970 return uv_translate_sys_error(WSAGetLastError()); \ 971 } \ 972 } \ 973 return 0; \ 974 } 975 976 #define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255) 977 #define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255) 978 #define VALIDATE_MULTICAST_LOOP(value) (1) 979 980 SOCKOPT_SETTER(ttl, 981 IP_TTL, 982 IPV6_HOPLIMIT, 983 VALIDATE_TTL) 984 SOCKOPT_SETTER(multicast_ttl, 985 IP_MULTICAST_TTL, 986 IPV6_MULTICAST_HOPS, 987 VALIDATE_MULTICAST_TTL) 988 SOCKOPT_SETTER(multicast_loop, 989 IP_MULTICAST_LOOP, 990 IPV6_MULTICAST_LOOP, 991 VALIDATE_MULTICAST_LOOP) 992 993 #undef SOCKOPT_SETTER 994 #undef VALIDATE_TTL 995 #undef VALIDATE_MULTICAST_TTL 996 #undef VALIDATE_MULTICAST_LOOP 997 998 999 /* This function is an egress point, i.e. it returns libuv errors rather than 1000 * system errors. 1001 */ 1002 int uv__udp_bind(uv_udp_t* handle, 1003 const struct sockaddr* addr, 1004 unsigned int addrlen, 1005 unsigned int flags) { 1006 int err; 1007 1008 err = uv__udp_maybe_bind(handle, addr, addrlen, flags); 1009 if (err) 1010 return uv_translate_sys_error(err); 1011 1012 return 0; 1013 } 1014 1015 1016 int uv__udp_connect(uv_udp_t* handle, 1017 const struct sockaddr* addr, 1018 unsigned int addrlen) { 1019 const struct sockaddr* bind_addr; 1020 int err; 1021 1022 if (!(handle->flags & UV_HANDLE_BOUND)) { 1023 if (addrlen == sizeof(uv_addr_ip4_any_)) 1024 bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; 1025 else if (addrlen == sizeof(uv_addr_ip6_any_)) 1026 bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; 1027 else 1028 return UV_EINVAL; 1029 1030 err = uv__udp_maybe_bind(handle, bind_addr, addrlen, 0); 1031 if (err) 1032 return uv_translate_sys_error(err); 1033 } 1034 1035 err = connect(handle->socket, addr, addrlen); 1036 if (err) 1037 return uv_translate_sys_error(WSAGetLastError()); 1038 1039 handle->flags |= UV_HANDLE_UDP_CONNECTED; 1040 1041 return 0; 1042 } 1043 1044 1045 int uv__udp_disconnect(uv_udp_t* handle) { 1046 int err; 1047 struct sockaddr_storage addr; 1048 1049 memset(&addr, 0, sizeof(addr)); 1050 1051 err = connect(handle->socket, (struct sockaddr*) &addr, sizeof(addr)); 1052 if (err) 1053 return uv_translate_sys_error(WSAGetLastError()); 1054 1055 handle->flags &= ~UV_HANDLE_UDP_CONNECTED; 1056 return 0; 1057 } 1058 1059 1060 /* This function is an egress point, i.e. it returns libuv errors rather than 1061 * system errors. 1062 */ 1063 int uv__udp_send(uv_udp_send_t* req, 1064 uv_udp_t* handle, 1065 const uv_buf_t bufs[], 1066 unsigned int nbufs, 1067 const struct sockaddr* addr, 1068 unsigned int addrlen, 1069 uv_udp_send_cb send_cb) { 1070 const struct sockaddr* bind_addr; 1071 int err; 1072 1073 if (!(handle->flags & UV_HANDLE_BOUND)) { 1074 if (addrlen == sizeof(uv_addr_ip4_any_)) 1075 bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; 1076 else if (addrlen == sizeof(uv_addr_ip6_any_)) 1077 bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; 1078 else 1079 return UV_EINVAL; 1080 1081 err = uv__udp_maybe_bind(handle, bind_addr, addrlen, 0); 1082 if (err) 1083 return uv_translate_sys_error(err); 1084 } 1085 1086 err = uv__send(req, handle, bufs, nbufs, addr, addrlen, send_cb); 1087 if (err) 1088 return uv_translate_sys_error(err); 1089 1090 return 0; 1091 } 1092 1093 1094 int uv__udp_try_send(uv_udp_t* handle, 1095 const uv_buf_t bufs[], 1096 unsigned int nbufs, 1097 const struct sockaddr* addr, 1098 unsigned int addrlen) { 1099 DWORD bytes; 1100 const struct sockaddr* bind_addr; 1101 struct sockaddr_storage converted; 1102 int err; 1103 1104 if (nbufs < 1) 1105 return UV_EINVAL; 1106 1107 if (addr != NULL) { 1108 err = uv__convert_to_localhost_if_unspecified(addr, &converted); 1109 if (err) 1110 return err; 1111 addr = (const struct sockaddr*) &converted; 1112 } 1113 1114 /* Already sending a message.*/ 1115 if (handle->send_queue_count != 0) 1116 return UV_EAGAIN; 1117 1118 if (!(handle->flags & UV_HANDLE_BOUND)) { 1119 if (addrlen == sizeof(uv_addr_ip4_any_)) 1120 bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; 1121 else if (addrlen == sizeof(uv_addr_ip6_any_)) 1122 bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; 1123 else 1124 return UV_EINVAL; 1125 err = uv__udp_maybe_bind(handle, bind_addr, addrlen, 0); 1126 if (err) 1127 return uv_translate_sys_error(err); 1128 } 1129 1130 err = WSASendTo(handle->socket, 1131 (WSABUF*)bufs, 1132 nbufs, 1133 &bytes, 1134 0, 1135 addr, 1136 addrlen, 1137 NULL, 1138 NULL); 1139 1140 if (err) 1141 return uv_translate_sys_error(WSAGetLastError()); 1142 1143 return bytes; 1144 } 1145 1146 1147 int uv__udp_try_send2(uv_udp_t* handle, 1148 unsigned int count, 1149 uv_buf_t* bufs[/*count*/], 1150 unsigned int nbufs[/*count*/], 1151 struct sockaddr* addrs[/*count*/]) { 1152 unsigned int i; 1153 int r; 1154 1155 for (i = 0; i < count; i++) { 1156 r = uv_udp_try_send(handle, bufs[i], nbufs[i], addrs[i]); 1157 if (r < 0) 1158 return i > 0 ? i : r; /* Error if first packet, else send count. */ 1159 } 1160 1161 return i; 1162 } 1163