Home | History | Annotate | Line # | Download | only in win
      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