xref: /libuv/src/win/tcp.c (revision d2d92b74)
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 /*
33  * Number of simultaneous pending AcceptEx calls.
34  */
35 const unsigned int uv_simultaneous_server_accepts = 32;
36 
37 /* A zero-size buffer for use by uv_tcp_read */
38 static char uv_zero_[] = "";
39 
uv__tcp_nodelay(uv_tcp_t * handle,SOCKET socket,int enable)40 static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
41   if (setsockopt(socket,
42                  IPPROTO_TCP,
43                  TCP_NODELAY,
44                  (const char*)&enable,
45                  sizeof enable) == -1) {
46     return WSAGetLastError();
47   }
48   return 0;
49 }
50 
51 
uv__tcp_keepalive(uv_tcp_t * handle,SOCKET socket,int enable,unsigned int delay)52 static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) {
53   if (setsockopt(socket,
54                  SOL_SOCKET,
55                  SO_KEEPALIVE,
56                  (const char*)&enable,
57                  sizeof enable) == -1) {
58     return WSAGetLastError();
59   }
60 
61   if (!enable)
62     return 0;
63 
64   if (delay < 1)
65     return UV_EINVAL;
66 
67   if (setsockopt(socket,
68                  IPPROTO_TCP,
69                  TCP_KEEPALIVE,
70                  (const char*)&delay,
71                  sizeof delay) == -1) {
72     return WSAGetLastError();
73   }
74 
75   return 0;
76 }
77 
78 
uv__tcp_set_socket(uv_loop_t * loop,uv_tcp_t * handle,SOCKET socket,int family,int imported)79 static int uv__tcp_set_socket(uv_loop_t* loop,
80                               uv_tcp_t* handle,
81                               SOCKET socket,
82                               int family,
83                               int imported) {
84   DWORD yes = 1;
85   int non_ifs_lsp;
86   int err;
87 
88   if (handle->socket != INVALID_SOCKET)
89     return UV_EBUSY;
90 
91   /* Set the socket to nonblocking mode */
92   if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
93     return WSAGetLastError();
94   }
95 
96   /* Make the socket non-inheritable */
97   if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0))
98     return GetLastError();
99 
100   /* Associate it with the I/O completion port. Use uv_handle_t pointer as
101    * completion key. */
102   if (CreateIoCompletionPort((HANDLE)socket,
103                              loop->iocp,
104                              (ULONG_PTR)socket,
105                              0) == NULL) {
106     if (imported) {
107       handle->flags |= UV_HANDLE_EMULATE_IOCP;
108     } else {
109       return GetLastError();
110     }
111   }
112 
113   if (family == AF_INET6) {
114     non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6;
115   } else {
116     non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4;
117   }
118 
119   if (!(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) {
120     UCHAR sfcnm_flags =
121         FILE_SKIP_SET_EVENT_ON_HANDLE | FILE_SKIP_COMPLETION_PORT_ON_SUCCESS;
122     if (!SetFileCompletionNotificationModes((HANDLE) socket, sfcnm_flags))
123       return GetLastError();
124     handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
125   }
126 
127   if (handle->flags & UV_HANDLE_TCP_NODELAY) {
128     err = uv__tcp_nodelay(handle, socket, 1);
129     if (err)
130       return err;
131   }
132 
133   /* TODO: Use stored delay. */
134   if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) {
135     err = uv__tcp_keepalive(handle, socket, 1, 60);
136     if (err)
137       return err;
138   }
139 
140   handle->socket = socket;
141 
142   if (family == AF_INET6) {
143     handle->flags |= UV_HANDLE_IPV6;
144   } else {
145     assert(!(handle->flags & UV_HANDLE_IPV6));
146   }
147 
148   return 0;
149 }
150 
151 
uv_tcp_init_ex(uv_loop_t * loop,uv_tcp_t * handle,unsigned int flags)152 int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags) {
153   int domain;
154 
155   /* Use the lower 8 bits for the domain */
156   domain = flags & 0xFF;
157   if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
158     return UV_EINVAL;
159 
160   if (flags & ~0xFF)
161     return UV_EINVAL;
162 
163   uv__stream_init(loop, (uv_stream_t*) handle, UV_TCP);
164   handle->tcp.serv.accept_reqs = NULL;
165   handle->tcp.serv.pending_accepts = NULL;
166   handle->socket = INVALID_SOCKET;
167   handle->reqs_pending = 0;
168   handle->tcp.serv.func_acceptex = NULL;
169   handle->tcp.conn.func_connectex = NULL;
170   handle->tcp.serv.processed_accepts = 0;
171   handle->delayed_error = 0;
172 
173   /* If anything fails beyond this point we need to remove the handle from
174    * the handle queue, since it was added by uv__handle_init in uv__stream_init.
175    */
176 
177   if (domain != AF_UNSPEC) {
178     SOCKET sock;
179     DWORD err;
180 
181     sock = socket(domain, SOCK_STREAM, 0);
182     if (sock == INVALID_SOCKET) {
183       err = WSAGetLastError();
184       uv__queue_remove(&handle->handle_queue);
185       return uv_translate_sys_error(err);
186     }
187 
188     err = uv__tcp_set_socket(handle->loop, handle, sock, domain, 0);
189     if (err) {
190       closesocket(sock);
191       uv__queue_remove(&handle->handle_queue);
192       return uv_translate_sys_error(err);
193     }
194 
195   }
196 
197   return 0;
198 }
199 
200 
uv_tcp_init(uv_loop_t * loop,uv_tcp_t * handle)201 int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
202   return uv_tcp_init_ex(loop, handle, AF_UNSPEC);
203 }
204 
205 
uv__process_tcp_shutdown_req(uv_loop_t * loop,uv_tcp_t * stream,uv_shutdown_t * req)206 void uv__process_tcp_shutdown_req(uv_loop_t* loop, uv_tcp_t* stream, uv_shutdown_t *req) {
207   int err;
208 
209   assert(req);
210   assert(stream->stream.conn.write_reqs_pending == 0);
211   assert(!(stream->flags & UV_HANDLE_SHUT));
212   assert(stream->flags & UV_HANDLE_CONNECTION);
213 
214   stream->stream.conn.shutdown_req = NULL;
215   UNREGISTER_HANDLE_REQ(loop, stream, req);
216 
217   err = 0;
218   if (stream->flags & UV_HANDLE_CLOSING)
219    /* The user destroyed the stream before we got to do the shutdown. */
220     err = UV_ECANCELED;
221   else if (shutdown(stream->socket, SD_SEND) == SOCKET_ERROR)
222     err = uv_translate_sys_error(WSAGetLastError());
223   else /* Success. */
224     stream->flags |= UV_HANDLE_SHUT;
225 
226   if (req->cb)
227     req->cb(req, err);
228 
229   DECREASE_PENDING_REQ_COUNT(stream);
230 }
231 
232 
uv__tcp_endgame(uv_loop_t * loop,uv_tcp_t * handle)233 void uv__tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
234   unsigned int i;
235   uv_tcp_accept_t* req;
236 
237   assert(handle->flags & UV_HANDLE_CLOSING);
238   assert(handle->reqs_pending == 0);
239   assert(!(handle->flags & UV_HANDLE_CLOSED));
240   assert(handle->socket == INVALID_SOCKET);
241 
242   if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) {
243     if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
244       for (i = 0; i < uv_simultaneous_server_accepts; i++) {
245         req = &handle->tcp.serv.accept_reqs[i];
246         if (req->wait_handle != INVALID_HANDLE_VALUE) {
247           UnregisterWait(req->wait_handle);
248           req->wait_handle = INVALID_HANDLE_VALUE;
249         }
250         if (req->event_handle != NULL) {
251           CloseHandle(req->event_handle);
252           req->event_handle = NULL;
253         }
254       }
255     }
256 
257     uv__free(handle->tcp.serv.accept_reqs);
258     handle->tcp.serv.accept_reqs = NULL;
259   }
260 
261   if (handle->flags & UV_HANDLE_CONNECTION &&
262       handle->flags & UV_HANDLE_EMULATE_IOCP) {
263     if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
264       UnregisterWait(handle->read_req.wait_handle);
265       handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
266     }
267     if (handle->read_req.event_handle != NULL) {
268       CloseHandle(handle->read_req.event_handle);
269       handle->read_req.event_handle = NULL;
270     }
271   }
272 
273   uv__handle_close(handle);
274 }
275 
276 
277 /* Unlike on Unix, here we don't set SO_REUSEADDR, because it doesn't just
278  * allow binding to addresses that are in use by sockets in TIME_WAIT, it
279  * effectively allows 'stealing' a port which is in use by another application.
280  *
281  * SO_EXCLUSIVEADDRUSE is also not good here because it does check all sockets,
282  * regardless of state, so we'd get an error even if the port is in use by a
283  * socket in TIME_WAIT state.
284  *
285  * See issue #1360.
286  *
287  */
uv__tcp_try_bind(uv_tcp_t * handle,const struct sockaddr * addr,unsigned int addrlen,unsigned int flags)288 static int uv__tcp_try_bind(uv_tcp_t* handle,
289                             const struct sockaddr* addr,
290                             unsigned int addrlen,
291                             unsigned int flags) {
292   DWORD err;
293   int r;
294 
295   /* There is no SO_REUSEPORT on Windows, Windows only knows SO_REUSEADDR.
296    * so we just return an error directly when UV_TCP_REUSEPORT is requested
297    * for binding the socket. */
298   if (flags & UV_TCP_REUSEPORT)
299     return ERROR_NOT_SUPPORTED;
300 
301   if (handle->socket == INVALID_SOCKET) {
302     SOCKET sock;
303 
304     /* Cannot set IPv6-only mode on non-IPv6 socket. */
305     if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
306       return ERROR_INVALID_PARAMETER;
307 
308     sock = socket(addr->sa_family, SOCK_STREAM, 0);
309     if (sock == INVALID_SOCKET) {
310       return WSAGetLastError();
311     }
312 
313     err = uv__tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0);
314     if (err) {
315       closesocket(sock);
316       return err;
317     }
318   }
319 
320 #ifdef IPV6_V6ONLY
321   if (addr->sa_family == AF_INET6) {
322     int on;
323 
324     on = (flags & UV_TCP_IPV6ONLY) != 0;
325 
326     /* TODO: how to handle errors? This may fail if there is no ipv4 stack
327      * available, or when run on XP/2003 which have no support for dualstack
328      * sockets. For now we're silently ignoring the error. */
329     setsockopt(handle->socket,
330                IPPROTO_IPV6,
331                IPV6_V6ONLY,
332                (const char*)&on,
333                sizeof on);
334   }
335 #endif
336 
337   r = bind(handle->socket, addr, addrlen);
338 
339   if (r == SOCKET_ERROR) {
340     err = WSAGetLastError();
341     if (err == WSAEADDRINUSE) {
342       /* Some errors are not to be reported until connect() or listen() */
343       handle->delayed_error = err;
344     } else {
345       return err;
346     }
347   }
348 
349   handle->flags |= UV_HANDLE_BOUND;
350 
351   return 0;
352 }
353 
354 
post_completion(void * context,BOOLEAN timed_out)355 static void CALLBACK post_completion(void* context, BOOLEAN timed_out) {
356   uv_req_t* req;
357   uv_tcp_t* handle;
358 
359   req = (uv_req_t*) context;
360   assert(req != NULL);
361   handle = (uv_tcp_t*)req->data;
362   assert(handle != NULL);
363   assert(!timed_out);
364 
365   if (!PostQueuedCompletionStatus(handle->loop->iocp,
366                                   req->u.io.overlapped.InternalHigh,
367                                   0,
368                                   &req->u.io.overlapped)) {
369     uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
370   }
371 }
372 
373 
post_write_completion(void * context,BOOLEAN timed_out)374 static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) {
375   uv_write_t* req;
376   uv_tcp_t* handle;
377 
378   req = (uv_write_t*) context;
379   assert(req != NULL);
380   handle = (uv_tcp_t*)req->handle;
381   assert(handle != NULL);
382   assert(!timed_out);
383 
384   if (!PostQueuedCompletionStatus(handle->loop->iocp,
385                                   req->u.io.overlapped.InternalHigh,
386                                   0,
387                                   &req->u.io.overlapped)) {
388     uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
389   }
390 }
391 
392 
uv__tcp_queue_accept(uv_tcp_t * handle,uv_tcp_accept_t * req)393 static void uv__tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
394   uv_loop_t* loop = handle->loop;
395   BOOL success;
396   DWORD bytes;
397   SOCKET accept_socket;
398   short family;
399 
400   assert(handle->flags & UV_HANDLE_LISTENING);
401   assert(req->accept_socket == INVALID_SOCKET);
402 
403   /* choose family and extension function */
404   if (handle->flags & UV_HANDLE_IPV6) {
405     family = AF_INET6;
406   } else {
407     family = AF_INET;
408   }
409 
410   /* Open a socket for the accepted connection. */
411   accept_socket = socket(family, SOCK_STREAM, 0);
412   if (accept_socket == INVALID_SOCKET) {
413     SET_REQ_ERROR(req, WSAGetLastError());
414     uv__insert_pending_req(loop, (uv_req_t*)req);
415     handle->reqs_pending++;
416     return;
417   }
418 
419   /* Make the socket non-inheritable */
420   if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) {
421     SET_REQ_ERROR(req, GetLastError());
422     uv__insert_pending_req(loop, (uv_req_t*)req);
423     handle->reqs_pending++;
424     closesocket(accept_socket);
425     return;
426   }
427 
428   /* Prepare the overlapped structure. */
429   memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
430   if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
431     assert(req->event_handle != NULL);
432     req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
433   }
434 
435   success = handle->tcp.serv.func_acceptex(handle->socket,
436                                           accept_socket,
437                                           (void*)req->accept_buffer,
438                                           0,
439                                           sizeof(struct sockaddr_storage),
440                                           sizeof(struct sockaddr_storage),
441                                           &bytes,
442                                           &req->u.io.overlapped);
443 
444   if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
445     /* Process the req without IOCP. */
446     req->accept_socket = accept_socket;
447     handle->reqs_pending++;
448     uv__insert_pending_req(loop, (uv_req_t*)req);
449   } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
450     /* The req will be processed with IOCP. */
451     req->accept_socket = accept_socket;
452     handle->reqs_pending++;
453     if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
454         req->wait_handle == INVALID_HANDLE_VALUE &&
455         !RegisterWaitForSingleObject(&req->wait_handle,
456           req->event_handle, post_completion, (void*) req,
457           INFINITE, WT_EXECUTEINWAITTHREAD)) {
458       SET_REQ_ERROR(req, GetLastError());
459       uv__insert_pending_req(loop, (uv_req_t*)req);
460     }
461   } else {
462     /* Make this req pending reporting an error. */
463     SET_REQ_ERROR(req, WSAGetLastError());
464     uv__insert_pending_req(loop, (uv_req_t*)req);
465     handle->reqs_pending++;
466     /* Destroy the preallocated client socket. */
467     closesocket(accept_socket);
468     /* Destroy the event handle */
469     if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
470       CloseHandle(req->event_handle);
471       req->event_handle = NULL;
472     }
473   }
474 }
475 
476 
uv__tcp_queue_read(uv_loop_t * loop,uv_tcp_t * handle)477 static void uv__tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
478   uv_read_t* req;
479   uv_buf_t buf;
480   int result;
481   DWORD bytes, flags;
482 
483   assert(handle->flags & UV_HANDLE_READING);
484   assert(!(handle->flags & UV_HANDLE_READ_PENDING));
485 
486   req = &handle->read_req;
487   memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
488 
489   handle->flags |= UV_HANDLE_ZERO_READ;
490   buf.base = (char*) &uv_zero_;
491   buf.len = 0;
492 
493   /* Prepare the overlapped structure. */
494   memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
495   if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
496     assert(req->event_handle != NULL);
497     req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
498   }
499 
500   flags = 0;
501   result = WSARecv(handle->socket,
502                    (WSABUF*)&buf,
503                    1,
504                    &bytes,
505                    &flags,
506                    &req->u.io.overlapped,
507                    NULL);
508 
509   handle->flags |= UV_HANDLE_READ_PENDING;
510   handle->reqs_pending++;
511 
512   if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
513     /* Process the req without IOCP. */
514     req->u.io.overlapped.InternalHigh = bytes;
515     uv__insert_pending_req(loop, (uv_req_t*)req);
516   } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
517     /* The req will be processed with IOCP. */
518     if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
519         req->wait_handle == INVALID_HANDLE_VALUE &&
520         !RegisterWaitForSingleObject(&req->wait_handle,
521           req->event_handle, post_completion, (void*) req,
522           INFINITE, WT_EXECUTEINWAITTHREAD)) {
523       SET_REQ_ERROR(req, GetLastError());
524       uv__insert_pending_req(loop, (uv_req_t*)req);
525     }
526   } else {
527     /* Make this req pending reporting an error. */
528     SET_REQ_ERROR(req, WSAGetLastError());
529     uv__insert_pending_req(loop, (uv_req_t*)req);
530   }
531 }
532 
533 
uv_tcp_close_reset(uv_tcp_t * handle,uv_close_cb close_cb)534 int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) {
535   struct linger l = { 1, 0 };
536 
537   /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */
538   if (uv__is_stream_shutting(handle))
539     return UV_EINVAL;
540 
541   if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, (const char*)&l, sizeof(l)))
542     return uv_translate_sys_error(WSAGetLastError());
543 
544   uv_close((uv_handle_t*) handle, close_cb);
545   return 0;
546 }
547 
548 
uv__tcp_listen(uv_tcp_t * handle,int backlog,uv_connection_cb cb)549 int uv__tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
550   unsigned int i, simultaneous_accepts;
551   uv_tcp_accept_t* req;
552   int err;
553 
554   assert(backlog > 0);
555 
556   if (handle->flags & UV_HANDLE_LISTENING) {
557     handle->stream.serv.connection_cb = cb;
558   }
559 
560   if (handle->flags & UV_HANDLE_READING) {
561     return WSAEISCONN;
562   }
563 
564   if (handle->delayed_error) {
565     return handle->delayed_error;
566   }
567 
568   if (!(handle->flags & UV_HANDLE_BOUND)) {
569     err = uv__tcp_try_bind(handle,
570                            (const struct sockaddr*) &uv_addr_ip4_any_,
571                            sizeof(uv_addr_ip4_any_),
572                            0);
573     if (err)
574       return err;
575     if (handle->delayed_error)
576       return handle->delayed_error;
577   }
578 
579   if (!handle->tcp.serv.func_acceptex) {
580     if (!uv__get_acceptex_function(handle->socket, &handle->tcp.serv.func_acceptex)) {
581       return WSAEAFNOSUPPORT;
582     }
583   }
584 
585   /* If this flag is set, we already made this listen call in xfer. */
586   if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
587       listen(handle->socket, backlog) == SOCKET_ERROR) {
588     return WSAGetLastError();
589   }
590 
591   handle->flags |= UV_HANDLE_LISTENING;
592   handle->stream.serv.connection_cb = cb;
593   INCREASE_ACTIVE_COUNT(loop, handle);
594 
595   simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
596     : uv_simultaneous_server_accepts;
597 
598   if (handle->tcp.serv.accept_reqs == NULL) {
599     handle->tcp.serv.accept_reqs =
600       uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
601     if (!handle->tcp.serv.accept_reqs) {
602       uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
603     }
604 
605     for (i = 0; i < simultaneous_accepts; i++) {
606       req = &handle->tcp.serv.accept_reqs[i];
607       UV_REQ_INIT(req, UV_ACCEPT);
608       req->accept_socket = INVALID_SOCKET;
609       req->data = handle;
610 
611       req->wait_handle = INVALID_HANDLE_VALUE;
612       if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
613         req->event_handle = CreateEvent(NULL, 0, 0, NULL);
614         if (req->event_handle == NULL) {
615           uv_fatal_error(GetLastError(), "CreateEvent");
616         }
617       } else {
618         req->event_handle = NULL;
619       }
620 
621       uv__tcp_queue_accept(handle, req);
622     }
623 
624     /* Initialize other unused requests too, because uv_tcp_endgame doesn't
625      * know how many requests were initialized, so it will try to clean up
626      * {uv_simultaneous_server_accepts} requests. */
627     for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) {
628       req = &handle->tcp.serv.accept_reqs[i];
629       UV_REQ_INIT(req, UV_ACCEPT);
630       req->accept_socket = INVALID_SOCKET;
631       req->data = handle;
632       req->wait_handle = INVALID_HANDLE_VALUE;
633       req->event_handle = NULL;
634     }
635   }
636 
637   return 0;
638 }
639 
640 
uv__tcp_accept(uv_tcp_t * server,uv_tcp_t * client)641 int uv__tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
642   int err = 0;
643   int family;
644 
645   uv_tcp_accept_t* req = server->tcp.serv.pending_accepts;
646 
647   if (!req) {
648     /* No valid connections found, so we error out. */
649     return WSAEWOULDBLOCK;
650   }
651 
652   if (req->accept_socket == INVALID_SOCKET) {
653     return WSAENOTCONN;
654   }
655 
656   if (server->flags & UV_HANDLE_IPV6) {
657     family = AF_INET6;
658   } else {
659     family = AF_INET;
660   }
661 
662   err = uv__tcp_set_socket(client->loop,
663                           client,
664                           req->accept_socket,
665                           family,
666                           0);
667   if (err) {
668     closesocket(req->accept_socket);
669   } else {
670     uv__connection_init((uv_stream_t*) client);
671     /* AcceptEx() implicitly binds the accepted socket. */
672     client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
673   }
674 
675   /* Prepare the req to pick up a new connection */
676   server->tcp.serv.pending_accepts = req->next_pending;
677   req->next_pending = NULL;
678   req->accept_socket = INVALID_SOCKET;
679 
680   if (!(server->flags & UV_HANDLE_CLOSING)) {
681     /* Check if we're in a middle of changing the number of pending accepts. */
682     if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) {
683       uv__tcp_queue_accept(server, req);
684     } else {
685       /* We better be switching to a single pending accept. */
686       assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT);
687 
688       server->tcp.serv.processed_accepts++;
689 
690       if (server->tcp.serv.processed_accepts >= uv_simultaneous_server_accepts) {
691         server->tcp.serv.processed_accepts = 0;
692         /*
693          * All previously queued accept requests are now processed.
694          * We now switch to queueing just a single accept.
695          */
696         uv__tcp_queue_accept(server, &server->tcp.serv.accept_reqs[0]);
697         server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
698         server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
699       }
700     }
701   }
702 
703   return err;
704 }
705 
706 
uv__tcp_read_start(uv_tcp_t * handle,uv_alloc_cb alloc_cb,uv_read_cb read_cb)707 int uv__tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
708     uv_read_cb read_cb) {
709   uv_loop_t* loop = handle->loop;
710 
711   handle->flags |= UV_HANDLE_READING;
712   handle->read_cb = read_cb;
713   handle->alloc_cb = alloc_cb;
714   INCREASE_ACTIVE_COUNT(loop, handle);
715 
716   /* If reading was stopped and then started again, there could still be a read
717    * request pending. */
718   if (!(handle->flags & UV_HANDLE_READ_PENDING)) {
719     if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
720         handle->read_req.event_handle == NULL) {
721       handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL);
722       if (handle->read_req.event_handle == NULL) {
723         uv_fatal_error(GetLastError(), "CreateEvent");
724       }
725     }
726     uv__tcp_queue_read(loop, handle);
727   }
728 
729   return 0;
730 }
731 
uv__is_loopback(const struct sockaddr_storage * storage)732 static int uv__is_loopback(const struct sockaddr_storage* storage) {
733   const struct sockaddr_in* in4;
734   const struct sockaddr_in6* in6;
735   int i;
736 
737   if (storage->ss_family == AF_INET) {
738     in4 = (const struct sockaddr_in*) storage;
739     return in4->sin_addr.S_un.S_un_b.s_b1 == 127;
740   }
741   if (storage->ss_family == AF_INET6) {
742     in6 = (const struct sockaddr_in6*) storage;
743     for (i = 0; i < 7; ++i) {
744       if (in6->sin6_addr.u.Word[i] != 0)
745         return 0;
746     }
747     return in6->sin6_addr.u.Word[7] == htons(1);
748   }
749   return 0;
750 }
751 
752 // Check if Windows version is 10.0.16299 or later
uv__is_fast_loopback_fail_supported(void)753 static int uv__is_fast_loopback_fail_supported(void) {
754   OSVERSIONINFOW os_info;
755   if (!pRtlGetVersion)
756     return 0;
757   pRtlGetVersion(&os_info);
758   if (os_info.dwMajorVersion < 10)
759     return 0;
760   if (os_info.dwMajorVersion > 10)
761     return 1;
762   if (os_info.dwMinorVersion > 0)
763     return 1;
764   return os_info.dwBuildNumber >= 16299;
765 }
766 
uv__tcp_try_connect(uv_connect_t * req,uv_tcp_t * handle,const struct sockaddr * addr,unsigned int addrlen,uv_connect_cb cb)767 static int uv__tcp_try_connect(uv_connect_t* req,
768                               uv_tcp_t* handle,
769                               const struct sockaddr* addr,
770                               unsigned int addrlen,
771                               uv_connect_cb cb) {
772   uv_loop_t* loop = handle->loop;
773   TCP_INITIAL_RTO_PARAMETERS retransmit_ioctl;
774   const struct sockaddr* bind_addr;
775   struct sockaddr_storage converted;
776   BOOL success;
777   DWORD bytes;
778   int err;
779 
780   err = uv__convert_to_localhost_if_unspecified(addr, &converted);
781   if (err)
782     return err;
783 
784   if (handle->delayed_error != 0)
785     goto out;
786 
787   if (!(handle->flags & UV_HANDLE_BOUND)) {
788     if (addrlen == sizeof(uv_addr_ip4_any_)) {
789       bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_;
790     } else if (addrlen == sizeof(uv_addr_ip6_any_)) {
791       bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
792     } else {
793       abort();
794     }
795     err = uv__tcp_try_bind(handle, bind_addr, addrlen, 0);
796     if (err)
797       return err;
798     if (handle->delayed_error != 0)
799       goto out;
800   }
801 
802   if (!handle->tcp.conn.func_connectex) {
803     if (!uv__get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) {
804       return WSAEAFNOSUPPORT;
805     }
806   }
807 
808   /* This makes connect() fail instantly if the target port on the localhost
809    * is not reachable, instead of waiting for 2s. We do not care if this fails.
810    * This only works on Windows version 10.0.16299 and later.
811    */
812   if (uv__is_fast_loopback_fail_supported() && uv__is_loopback(&converted)) {
813     memset(&retransmit_ioctl, 0, sizeof(retransmit_ioctl));
814     retransmit_ioctl.Rtt = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS;
815     retransmit_ioctl.MaxSynRetransmissions = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS;
816     WSAIoctl(handle->socket,
817              SIO_TCP_INITIAL_RTO,
818              &retransmit_ioctl,
819              sizeof(retransmit_ioctl),
820              NULL,
821              0,
822              &bytes,
823              NULL,
824              NULL);
825   }
826 
827 out:
828 
829   UV_REQ_INIT(req, UV_CONNECT);
830   req->handle = (uv_stream_t*) handle;
831   req->cb = cb;
832   memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
833 
834   if (handle->delayed_error != 0) {
835     /* Process the req without IOCP. */
836     handle->reqs_pending++;
837     REGISTER_HANDLE_REQ(loop, handle, req);
838     uv__insert_pending_req(loop, (uv_req_t*)req);
839     return 0;
840   }
841 
842   success = handle->tcp.conn.func_connectex(handle->socket,
843                                             (const struct sockaddr*) &converted,
844                                             addrlen,
845                                             NULL,
846                                             0,
847                                             &bytes,
848                                             &req->u.io.overlapped);
849 
850   if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
851     /* Process the req without IOCP. */
852     handle->reqs_pending++;
853     REGISTER_HANDLE_REQ(loop, handle, req);
854     uv__insert_pending_req(loop, (uv_req_t*)req);
855   } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
856     /* The req will be processed with IOCP. */
857     handle->reqs_pending++;
858     REGISTER_HANDLE_REQ(loop, handle, req);
859   } else {
860     return WSAGetLastError();
861   }
862 
863   return 0;
864 }
865 
866 
uv_tcp_getsockname(const uv_tcp_t * handle,struct sockaddr * name,int * namelen)867 int uv_tcp_getsockname(const uv_tcp_t* handle,
868                        struct sockaddr* name,
869                        int* namelen) {
870 
871   return uv__getsockpeername((const uv_handle_t*) handle,
872                              getsockname,
873                              name,
874                              namelen,
875                              handle->delayed_error);
876 }
877 
878 
uv_tcp_getpeername(const uv_tcp_t * handle,struct sockaddr * name,int * namelen)879 int uv_tcp_getpeername(const uv_tcp_t* handle,
880                        struct sockaddr* name,
881                        int* namelen) {
882 
883   return uv__getsockpeername((const uv_handle_t*) handle,
884                              getpeername,
885                              name,
886                              namelen,
887                              handle->delayed_error);
888 }
889 
890 
uv__tcp_write(uv_loop_t * loop,uv_write_t * req,uv_tcp_t * handle,const uv_buf_t bufs[],unsigned int nbufs,uv_write_cb cb)891 int uv__tcp_write(uv_loop_t* loop,
892                  uv_write_t* req,
893                  uv_tcp_t* handle,
894                  const uv_buf_t bufs[],
895                  unsigned int nbufs,
896                  uv_write_cb cb) {
897   int result;
898   DWORD bytes;
899 
900   UV_REQ_INIT(req, UV_WRITE);
901   req->handle = (uv_stream_t*) handle;
902   req->cb = cb;
903 
904   /* Prepare the overlapped structure. */
905   memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
906   if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
907     req->event_handle = CreateEvent(NULL, 0, 0, NULL);
908     if (req->event_handle == NULL) {
909       uv_fatal_error(GetLastError(), "CreateEvent");
910     }
911     req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
912     req->wait_handle = INVALID_HANDLE_VALUE;
913   }
914 
915   result = WSASend(handle->socket,
916                    (WSABUF*) bufs,
917                    nbufs,
918                    &bytes,
919                    0,
920                    &req->u.io.overlapped,
921                    NULL);
922 
923   if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
924     /* Request completed immediately. */
925     req->u.io.queued_bytes = 0;
926     handle->reqs_pending++;
927     handle->stream.conn.write_reqs_pending++;
928     REGISTER_HANDLE_REQ(loop, handle, req);
929     uv__insert_pending_req(loop, (uv_req_t*) req);
930   } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
931     /* Request queued by the kernel. */
932     req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs);
933     handle->reqs_pending++;
934     handle->stream.conn.write_reqs_pending++;
935     REGISTER_HANDLE_REQ(loop, handle, req);
936     handle->write_queue_size += req->u.io.queued_bytes;
937     if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
938         !RegisterWaitForSingleObject(&req->wait_handle,
939           req->event_handle, post_write_completion, (void*) req,
940           INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) {
941       SET_REQ_ERROR(req, GetLastError());
942       uv__insert_pending_req(loop, (uv_req_t*)req);
943     }
944   } else {
945     /* Send failed due to an error, report it later */
946     req->u.io.queued_bytes = 0;
947     handle->reqs_pending++;
948     handle->stream.conn.write_reqs_pending++;
949     REGISTER_HANDLE_REQ(loop, handle, req);
950     SET_REQ_ERROR(req, WSAGetLastError());
951     uv__insert_pending_req(loop, (uv_req_t*) req);
952   }
953 
954   return 0;
955 }
956 
957 
uv__tcp_try_write(uv_tcp_t * handle,const uv_buf_t bufs[],unsigned int nbufs)958 int uv__tcp_try_write(uv_tcp_t* handle,
959                      const uv_buf_t bufs[],
960                      unsigned int nbufs) {
961   int result;
962   DWORD bytes;
963 
964   if (handle->stream.conn.write_reqs_pending > 0)
965     return UV_EAGAIN;
966 
967   result = WSASend(handle->socket,
968                    (WSABUF*) bufs,
969                    nbufs,
970                    &bytes,
971                    0,
972                    NULL,
973                    NULL);
974 
975   if (result == SOCKET_ERROR)
976     return uv_translate_sys_error(WSAGetLastError());
977   else
978     return bytes;
979 }
980 
981 
uv__process_tcp_read_req(uv_loop_t * loop,uv_tcp_t * handle,uv_req_t * req)982 void uv__process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
983     uv_req_t* req) {
984   DWORD bytes, flags, err;
985   uv_buf_t buf;
986   int count;
987 
988   assert(handle->type == UV_TCP);
989 
990   handle->flags &= ~UV_HANDLE_READ_PENDING;
991 
992   if (!REQ_SUCCESS(req)) {
993     /* An error occurred doing the read. */
994     if ((handle->flags & UV_HANDLE_READING) ||
995         !(handle->flags & UV_HANDLE_ZERO_READ)) {
996       handle->flags &= ~UV_HANDLE_READING;
997       DECREASE_ACTIVE_COUNT(loop, handle);
998       buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
999             uv_buf_init(NULL, 0) : handle->tcp.conn.read_buffer;
1000 
1001       err = GET_REQ_SOCK_ERROR(req);
1002 
1003       if (err == WSAECONNABORTED) {
1004         /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
1005          */
1006         err = WSAECONNRESET;
1007       }
1008       handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
1009 
1010       handle->read_cb((uv_stream_t*)handle,
1011                       uv_translate_sys_error(err),
1012                       &buf);
1013     }
1014   } else {
1015     if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
1016       /* The read was done with a non-zero buffer length. */
1017       if (req->u.io.overlapped.InternalHigh > 0) {
1018         /* Successful read */
1019         handle->read_cb((uv_stream_t*)handle,
1020                         req->u.io.overlapped.InternalHigh,
1021                         &handle->tcp.conn.read_buffer);
1022         /* Read again only if bytes == buf.len */
1023         if (req->u.io.overlapped.InternalHigh < handle->tcp.conn.read_buffer.len) {
1024           goto done;
1025         }
1026       } else {
1027         /* Connection closed */
1028         if (handle->flags & UV_HANDLE_READING) {
1029           handle->flags &= ~UV_HANDLE_READING;
1030           DECREASE_ACTIVE_COUNT(loop, handle);
1031         }
1032 
1033         buf.base = 0;
1034         buf.len = 0;
1035         handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->tcp.conn.read_buffer);
1036         goto done;
1037       }
1038     }
1039 
1040     /* Do nonblocking reads until the buffer is empty */
1041     count = 32;
1042     while ((handle->flags & UV_HANDLE_READING) && (count-- > 0)) {
1043       buf = uv_buf_init(NULL, 0);
1044       handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
1045       if (buf.base == NULL || buf.len == 0) {
1046         handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
1047         break;
1048       }
1049       assert(buf.base != NULL);
1050 
1051       flags = 0;
1052       if (WSARecv(handle->socket,
1053                   (WSABUF*)&buf,
1054                   1,
1055                   &bytes,
1056                   &flags,
1057                   NULL,
1058                   NULL) != SOCKET_ERROR) {
1059         if (bytes > 0) {
1060           /* Successful read */
1061           handle->read_cb((uv_stream_t*)handle, bytes, &buf);
1062           /* Read again only if bytes == buf.len */
1063           if (bytes < buf.len) {
1064             break;
1065           }
1066         } else {
1067           /* Connection closed */
1068           handle->flags &= ~UV_HANDLE_READING;
1069           DECREASE_ACTIVE_COUNT(loop, handle);
1070 
1071           handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf);
1072           break;
1073         }
1074       } else {
1075         err = WSAGetLastError();
1076         if (err == WSAEWOULDBLOCK) {
1077           /* Read buffer was completely empty, report a 0-byte read. */
1078           handle->read_cb((uv_stream_t*)handle, 0, &buf);
1079         } else {
1080           /* Ouch! serious error. */
1081           handle->flags &= ~UV_HANDLE_READING;
1082           DECREASE_ACTIVE_COUNT(loop, handle);
1083 
1084           if (err == WSAECONNABORTED) {
1085             /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with
1086              * Unix. */
1087             err = WSAECONNRESET;
1088           }
1089           handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
1090 
1091           handle->read_cb((uv_stream_t*)handle,
1092                           uv_translate_sys_error(err),
1093                           &buf);
1094         }
1095         break;
1096       }
1097     }
1098 
1099 done:
1100     /* Post another read if still reading and not closing. */
1101     if ((handle->flags & UV_HANDLE_READING) &&
1102         !(handle->flags & UV_HANDLE_READ_PENDING)) {
1103       uv__tcp_queue_read(loop, handle);
1104     }
1105   }
1106 
1107   DECREASE_PENDING_REQ_COUNT(handle);
1108 }
1109 
1110 
uv__process_tcp_write_req(uv_loop_t * loop,uv_tcp_t * handle,uv_write_t * req)1111 void uv__process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
1112     uv_write_t* req) {
1113   int err;
1114 
1115   assert(handle->type == UV_TCP);
1116 
1117   assert(handle->write_queue_size >= req->u.io.queued_bytes);
1118   handle->write_queue_size -= req->u.io.queued_bytes;
1119 
1120   UNREGISTER_HANDLE_REQ(loop, handle, req);
1121 
1122   if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
1123     if (req->wait_handle != INVALID_HANDLE_VALUE) {
1124       UnregisterWait(req->wait_handle);
1125       req->wait_handle = INVALID_HANDLE_VALUE;
1126     }
1127     if (req->event_handle != NULL) {
1128       CloseHandle(req->event_handle);
1129       req->event_handle = NULL;
1130     }
1131   }
1132 
1133   if (req->cb) {
1134     err = uv_translate_sys_error(GET_REQ_SOCK_ERROR(req));
1135     if (err == UV_ECONNABORTED) {
1136       /* use UV_ECANCELED for consistency with Unix */
1137       err = UV_ECANCELED;
1138     }
1139     req->cb(req, err);
1140   }
1141 
1142   handle->stream.conn.write_reqs_pending--;
1143   if (handle->stream.conn.write_reqs_pending == 0) {
1144     if (handle->flags & UV_HANDLE_CLOSING) {
1145       closesocket(handle->socket);
1146       handle->socket = INVALID_SOCKET;
1147     }
1148     if (uv__is_stream_shutting(handle))
1149       uv__process_tcp_shutdown_req(loop,
1150                                    handle,
1151                                    handle->stream.conn.shutdown_req);
1152   }
1153 
1154   DECREASE_PENDING_REQ_COUNT(handle);
1155 }
1156 
1157 
uv__process_tcp_accept_req(uv_loop_t * loop,uv_tcp_t * handle,uv_req_t * raw_req)1158 void uv__process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
1159     uv_req_t* raw_req) {
1160   uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req;
1161   int err;
1162 
1163   assert(handle->type == UV_TCP);
1164 
1165   /* If handle->accepted_socket is not a valid socket, then uv_queue_accept
1166    * must have failed. This is a serious error. We stop accepting connections
1167    * and report this error to the connection callback. */
1168   if (req->accept_socket == INVALID_SOCKET) {
1169     if (handle->flags & UV_HANDLE_LISTENING) {
1170       handle->flags &= ~UV_HANDLE_LISTENING;
1171       DECREASE_ACTIVE_COUNT(loop, handle);
1172       if (handle->stream.serv.connection_cb) {
1173         err = GET_REQ_SOCK_ERROR(req);
1174         handle->stream.serv.connection_cb((uv_stream_t*)handle,
1175                                       uv_translate_sys_error(err));
1176       }
1177     }
1178   } else if (REQ_SUCCESS(req) &&
1179       setsockopt(req->accept_socket,
1180                   SOL_SOCKET,
1181                   SO_UPDATE_ACCEPT_CONTEXT,
1182                   (char*)&handle->socket,
1183                   sizeof(handle->socket)) == 0) {
1184     req->next_pending = handle->tcp.serv.pending_accepts;
1185     handle->tcp.serv.pending_accepts = req;
1186 
1187     /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */
1188     if (handle->stream.serv.connection_cb) {
1189       handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
1190     }
1191   } else {
1192     /* Error related to accepted socket is ignored because the server socket
1193      * may still be healthy. If the server socket is broken uv_queue_accept
1194      * will detect it. */
1195     closesocket(req->accept_socket);
1196     req->accept_socket = INVALID_SOCKET;
1197     if (handle->flags & UV_HANDLE_LISTENING) {
1198       uv__tcp_queue_accept(handle, req);
1199     }
1200   }
1201 
1202   DECREASE_PENDING_REQ_COUNT(handle);
1203 }
1204 
1205 
uv__process_tcp_connect_req(uv_loop_t * loop,uv_tcp_t * handle,uv_connect_t * req)1206 void uv__process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
1207     uv_connect_t* req) {
1208   int err;
1209 
1210   assert(handle->type == UV_TCP);
1211 
1212   UNREGISTER_HANDLE_REQ(loop, handle, req);
1213 
1214   err = 0;
1215   if (handle->delayed_error) {
1216     /* To smooth over the differences between unixes errors that
1217      * were reported synchronously on the first connect can be delayed
1218      * until the next tick--which is now.
1219      */
1220     err = handle->delayed_error;
1221     handle->delayed_error = 0;
1222   } else if (REQ_SUCCESS(req)) {
1223     if (handle->flags & UV_HANDLE_CLOSING) {
1224       /* use UV_ECANCELED for consistency with Unix */
1225       err = ERROR_OPERATION_ABORTED;
1226     } else if (setsockopt(handle->socket,
1227                           SOL_SOCKET,
1228                           SO_UPDATE_CONNECT_CONTEXT,
1229                           NULL,
1230                           0) == 0) {
1231       uv__connection_init((uv_stream_t*)handle);
1232       handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
1233     } else {
1234       err = WSAGetLastError();
1235     }
1236   } else {
1237     err = GET_REQ_SOCK_ERROR(req);
1238   }
1239   req->cb(req, uv_translate_sys_error(err));
1240 
1241   DECREASE_PENDING_REQ_COUNT(handle);
1242 }
1243 
1244 
uv__tcp_xfer_export(uv_tcp_t * handle,int target_pid,uv__ipc_socket_xfer_type_t * xfer_type,uv__ipc_socket_xfer_info_t * xfer_info)1245 int uv__tcp_xfer_export(uv_tcp_t* handle,
1246                         int target_pid,
1247                         uv__ipc_socket_xfer_type_t* xfer_type,
1248                         uv__ipc_socket_xfer_info_t* xfer_info) {
1249   if (handle->flags & UV_HANDLE_CONNECTION) {
1250     *xfer_type = UV__IPC_SOCKET_XFER_TCP_CONNECTION;
1251   } else {
1252     *xfer_type = UV__IPC_SOCKET_XFER_TCP_SERVER;
1253     /* We're about to share the socket with another process. Because this is a
1254      * listening socket, we assume that the other process will be accepting
1255      * connections on it. Thus, before sharing the socket with another process,
1256      * we call listen here in the parent process. */
1257     if (!(handle->flags & UV_HANDLE_LISTENING)) {
1258       if (!(handle->flags & UV_HANDLE_BOUND)) {
1259         return ERROR_NOT_SUPPORTED;
1260       }
1261       if (handle->delayed_error == 0 &&
1262           listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) {
1263         handle->delayed_error = WSAGetLastError();
1264       }
1265     }
1266   }
1267 
1268   if (WSADuplicateSocketW(handle->socket, target_pid, &xfer_info->socket_info))
1269     return WSAGetLastError();
1270   xfer_info->delayed_error = handle->delayed_error;
1271 
1272   /* Mark the local copy of the handle as 'shared' so we behave in a way that's
1273    * friendly to the process(es) that we share the socket with. */
1274   handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
1275 
1276   return 0;
1277 }
1278 
1279 
uv__tcp_xfer_import(uv_tcp_t * tcp,uv__ipc_socket_xfer_type_t xfer_type,uv__ipc_socket_xfer_info_t * xfer_info)1280 int uv__tcp_xfer_import(uv_tcp_t* tcp,
1281                         uv__ipc_socket_xfer_type_t xfer_type,
1282                         uv__ipc_socket_xfer_info_t* xfer_info) {
1283   int err;
1284   SOCKET socket;
1285 
1286   assert(xfer_type == UV__IPC_SOCKET_XFER_TCP_SERVER ||
1287          xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION);
1288 
1289   socket = WSASocketW(FROM_PROTOCOL_INFO,
1290                       FROM_PROTOCOL_INFO,
1291                       FROM_PROTOCOL_INFO,
1292                       &xfer_info->socket_info,
1293                       0,
1294                       WSA_FLAG_OVERLAPPED);
1295 
1296   if (socket == INVALID_SOCKET) {
1297     return WSAGetLastError();
1298   }
1299 
1300   err = uv__tcp_set_socket(
1301       tcp->loop, tcp, socket, xfer_info->socket_info.iAddressFamily, 1);
1302   if (err) {
1303     closesocket(socket);
1304     return err;
1305   }
1306 
1307   tcp->delayed_error = xfer_info->delayed_error;
1308   tcp->flags |= UV_HANDLE_BOUND | UV_HANDLE_SHARED_TCP_SOCKET;
1309 
1310   if (xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION) {
1311     uv__connection_init((uv_stream_t*)tcp);
1312     tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
1313   }
1314 
1315   return 0;
1316 }
1317 
1318 
uv_tcp_nodelay(uv_tcp_t * handle,int enable)1319 int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
1320   int err;
1321 
1322   if (handle->socket != INVALID_SOCKET) {
1323     err = uv__tcp_nodelay(handle, handle->socket, enable);
1324     if (err)
1325       return uv_translate_sys_error(err);
1326   }
1327 
1328   if (enable) {
1329     handle->flags |= UV_HANDLE_TCP_NODELAY;
1330   } else {
1331     handle->flags &= ~UV_HANDLE_TCP_NODELAY;
1332   }
1333 
1334   return 0;
1335 }
1336 
1337 
uv_tcp_keepalive(uv_tcp_t * handle,int enable,unsigned int delay)1338 int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
1339   int err;
1340 
1341   if (handle->socket != INVALID_SOCKET) {
1342     err = uv__tcp_keepalive(handle, handle->socket, enable, delay);
1343     if (err)
1344       return uv_translate_sys_error(err);
1345   }
1346 
1347   if (enable) {
1348     handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
1349   } else {
1350     handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
1351   }
1352 
1353   /* TODO: Store delay if handle->socket isn't created yet. */
1354 
1355   return 0;
1356 }
1357 
1358 
uv_tcp_simultaneous_accepts(uv_tcp_t * handle,int enable)1359 int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
1360   if (handle->flags & UV_HANDLE_CONNECTION) {
1361     return UV_EINVAL;
1362   }
1363 
1364   /* Check if we're already in the desired mode. */
1365   if ((enable && !(handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) ||
1366       (!enable && handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) {
1367     return 0;
1368   }
1369 
1370   /* Don't allow switching from single pending accept to many. */
1371   if (enable) {
1372     return UV_ENOTSUP;
1373   }
1374 
1375   /* Check if we're in a middle of changing the number of pending accepts. */
1376   if (handle->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING) {
1377     return 0;
1378   }
1379 
1380   handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
1381 
1382   /* Flip the changing flag if we have already queued multiple accepts. */
1383   if (handle->flags & UV_HANDLE_LISTENING) {
1384     handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
1385   }
1386 
1387   return 0;
1388 }
1389 
1390 
uv__tcp_try_cancel_reqs(uv_tcp_t * tcp)1391 static void uv__tcp_try_cancel_reqs(uv_tcp_t* tcp) {
1392   SOCKET socket;
1393   int non_ifs_lsp;
1394   int reading;
1395   int writing;
1396 
1397   socket = tcp->socket;
1398   reading = tcp->flags & UV_HANDLE_READ_PENDING;
1399   writing = tcp->stream.conn.write_reqs_pending > 0;
1400   if (!reading && !writing)
1401     return;
1402 
1403   /* TODO: in libuv v2, keep explicit track of write_reqs, so we can cancel
1404    * them each explicitly with CancelIoEx (like unix). */
1405   if (reading)
1406     CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped);
1407   if (writing)
1408     CancelIo((HANDLE) socket);
1409 
1410   /* Check if we have any non-IFS LSPs stacked on top of TCP */
1411   non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
1412                                                 uv_tcp_non_ifs_lsp_ipv4;
1413 
1414   /* If there are non-ifs LSPs then try to obtain a base handle for the socket.
1415    */
1416   if (non_ifs_lsp) {
1417     DWORD bytes;
1418     if (WSAIoctl(socket,
1419                  SIO_BASE_HANDLE,
1420                  NULL,
1421                  0,
1422                  &socket,
1423                  sizeof socket,
1424                  &bytes,
1425                  NULL,
1426                  NULL) != 0) {
1427       /* Failed. We can't do CancelIo. */
1428       return;
1429     }
1430   }
1431 
1432   assert(socket != 0 && socket != INVALID_SOCKET);
1433 
1434   if (socket != tcp->socket) {
1435     if (reading)
1436       CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped);
1437     if (writing)
1438       CancelIo((HANDLE) socket);
1439   }
1440 }
1441 
1442 
uv__tcp_close(uv_loop_t * loop,uv_tcp_t * tcp)1443 void uv__tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
1444   if (tcp->flags & UV_HANDLE_CONNECTION) {
1445     if (tcp->flags & UV_HANDLE_READING) {
1446       uv_read_stop((uv_stream_t*) tcp);
1447     }
1448     uv__tcp_try_cancel_reqs(tcp);
1449   } else {
1450     if (tcp->tcp.serv.accept_reqs != NULL) {
1451       /* First close the incoming sockets to cancel the accept operations before
1452        * we free their resources. */
1453       unsigned int i;
1454       for (i = 0; i < uv_simultaneous_server_accepts; i++) {
1455         uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i];
1456         if (req->accept_socket != INVALID_SOCKET) {
1457           closesocket(req->accept_socket);
1458           req->accept_socket = INVALID_SOCKET;
1459         }
1460       }
1461     }
1462     assert(!(tcp->flags & UV_HANDLE_READING));
1463   }
1464 
1465   if (tcp->flags & UV_HANDLE_LISTENING) {
1466     tcp->flags &= ~UV_HANDLE_LISTENING;
1467     DECREASE_ACTIVE_COUNT(loop, tcp);
1468   }
1469 
1470   tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
1471   uv__handle_closing(tcp);
1472 
1473   /* If any overlapped req failed to cancel, calling `closesocket` now would
1474    * cause Win32 to send an RST packet. Try to avoid that for writes, if
1475    * possibly applicable, by waiting to process the completion notifications
1476    * first (which typically should be cancellations). There's not much we can
1477    * do about canceled reads, which also will generate an RST packet. */
1478   if (!(tcp->flags & UV_HANDLE_CONNECTION) ||
1479       tcp->stream.conn.write_reqs_pending == 0) {
1480     closesocket(tcp->socket);
1481     tcp->socket = INVALID_SOCKET;
1482   }
1483 
1484   if (tcp->reqs_pending == 0)
1485     uv__want_endgame(loop, (uv_handle_t*) tcp);
1486 }
1487 
1488 
uv_tcp_open(uv_tcp_t * handle,uv_os_sock_t sock)1489 int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
1490   WSAPROTOCOL_INFOW protocol_info;
1491   int opt_len;
1492   int err;
1493   struct sockaddr_storage saddr;
1494   int saddr_len;
1495 
1496   /* Detect the address family of the socket. */
1497   opt_len = (int) sizeof protocol_info;
1498   if (getsockopt(sock,
1499                  SOL_SOCKET,
1500                  SO_PROTOCOL_INFOW,
1501                  (char*) &protocol_info,
1502                  &opt_len) == SOCKET_ERROR) {
1503     return uv_translate_sys_error(GetLastError());
1504   }
1505 
1506   err = uv__tcp_set_socket(handle->loop,
1507                           handle,
1508                           sock,
1509                           protocol_info.iAddressFamily,
1510                           1);
1511   if (err) {
1512     return uv_translate_sys_error(err);
1513   }
1514 
1515   /* Support already active socket. */
1516   saddr_len = sizeof(saddr);
1517   if (!uv_tcp_getsockname(handle, (struct sockaddr*) &saddr, &saddr_len)) {
1518     /* Socket is already bound. */
1519     handle->flags |= UV_HANDLE_BOUND;
1520     saddr_len = sizeof(saddr);
1521     if (!uv_tcp_getpeername(handle, (struct sockaddr*) &saddr, &saddr_len)) {
1522       /* Socket is already connected. */
1523       uv__connection_init((uv_stream_t*) handle);
1524       handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
1525     }
1526   }
1527 
1528   return 0;
1529 }
1530 
1531 
1532 /* This function is an egress point, i.e. it returns libuv errors rather than
1533  * system errors.
1534  */
uv__tcp_bind(uv_tcp_t * handle,const struct sockaddr * addr,unsigned int addrlen,unsigned int flags)1535 int uv__tcp_bind(uv_tcp_t* handle,
1536                  const struct sockaddr* addr,
1537                  unsigned int addrlen,
1538                  unsigned int flags) {
1539   int err;
1540 
1541   err = uv__tcp_try_bind(handle, addr, addrlen, flags);
1542   if (err)
1543     return uv_translate_sys_error(err);
1544 
1545   return 0;
1546 }
1547 
1548 
1549 /* This function is an egress point, i.e. it returns libuv errors rather than
1550  * system errors.
1551  */
uv__tcp_connect(uv_connect_t * req,uv_tcp_t * handle,const struct sockaddr * addr,unsigned int addrlen,uv_connect_cb cb)1552 int uv__tcp_connect(uv_connect_t* req,
1553                     uv_tcp_t* handle,
1554                     const struct sockaddr* addr,
1555                     unsigned int addrlen,
1556                     uv_connect_cb cb) {
1557   int err;
1558 
1559   err = uv__tcp_try_connect(req, handle, addr, addrlen, cb);
1560   if (err)
1561     return uv_translate_sys_error(err);
1562 
1563   return 0;
1564 }
1565 
1566 
uv_socketpair(int type,int protocol,uv_os_sock_t fds[2],int flags0,int flags1)1567 int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) {
1568   SOCKET server = INVALID_SOCKET;
1569   SOCKET client0 = INVALID_SOCKET;
1570   SOCKET client1 = INVALID_SOCKET;
1571   SOCKADDR_IN name;
1572   LPFN_ACCEPTEX func_acceptex;
1573   WSAOVERLAPPED overlap;
1574   char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32];
1575   int namelen;
1576   int err;
1577   DWORD bytes;
1578   DWORD flags;
1579   DWORD client0_flags = WSA_FLAG_NO_HANDLE_INHERIT;
1580   DWORD client1_flags = WSA_FLAG_NO_HANDLE_INHERIT;
1581 
1582   if (flags0 & UV_NONBLOCK_PIPE)
1583       client0_flags |= WSA_FLAG_OVERLAPPED;
1584   if (flags1 & UV_NONBLOCK_PIPE)
1585       client1_flags |= WSA_FLAG_OVERLAPPED;
1586 
1587   server = WSASocketW(AF_INET, type, protocol, NULL, 0,
1588                       WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
1589   if (server == INVALID_SOCKET)
1590     goto wsaerror;
1591   if (!SetHandleInformation((HANDLE) server, HANDLE_FLAG_INHERIT, 0))
1592     goto error;
1593   name.sin_family = AF_INET;
1594   name.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1595   name.sin_port = 0;
1596   if (bind(server, (SOCKADDR*) &name, sizeof(name)) != 0)
1597     goto wsaerror;
1598   if (listen(server, 1) != 0)
1599     goto wsaerror;
1600   namelen = sizeof(name);
1601   if (getsockname(server, (SOCKADDR*) &name, &namelen) != 0)
1602     goto wsaerror;
1603   client0 = WSASocketW(AF_INET, type, protocol, NULL, 0, client0_flags);
1604   if (client0 == INVALID_SOCKET)
1605     goto wsaerror;
1606   if (!SetHandleInformation((HANDLE) client0, HANDLE_FLAG_INHERIT, 0))
1607     goto error;
1608   if (connect(client0, (SOCKADDR*) &name, sizeof(name)) != 0)
1609     goto wsaerror;
1610   client1 = WSASocketW(AF_INET, type, protocol, NULL, 0, client1_flags);
1611   if (client1 == INVALID_SOCKET)
1612     goto wsaerror;
1613   if (!SetHandleInformation((HANDLE) client1, HANDLE_FLAG_INHERIT, 0))
1614     goto error;
1615   if (!uv__get_acceptex_function(server, &func_acceptex)) {
1616     err = WSAEAFNOSUPPORT;
1617     goto cleanup;
1618   }
1619   memset(&overlap, 0, sizeof(overlap));
1620   if (!func_acceptex(server,
1621                      client1,
1622                      accept_buffer,
1623                      0,
1624                      sizeof(struct sockaddr_storage),
1625                      sizeof(struct sockaddr_storage),
1626                      &bytes,
1627                      &overlap)) {
1628     err = WSAGetLastError();
1629     if (err == ERROR_IO_PENDING) {
1630       /* Result should complete immediately, since we already called connect,
1631        * but empirically, we sometimes have to poll the kernel a couple times
1632        * until it notices that. */
1633       while (!WSAGetOverlappedResult(client1, &overlap, &bytes, FALSE, &flags)) {
1634         err = WSAGetLastError();
1635         if (err != WSA_IO_INCOMPLETE)
1636           goto cleanup;
1637         SwitchToThread();
1638       }
1639     }
1640     else {
1641       goto cleanup;
1642     }
1643   }
1644   if (setsockopt(client1, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
1645                   (char*) &server, sizeof(server)) != 0) {
1646     goto wsaerror;
1647   }
1648 
1649   closesocket(server);
1650 
1651   fds[0] = client0;
1652   fds[1] = client1;
1653 
1654   return 0;
1655 
1656  wsaerror:
1657     err = WSAGetLastError();
1658     goto cleanup;
1659 
1660  error:
1661     err = GetLastError();
1662     goto cleanup;
1663 
1664  cleanup:
1665     if (server != INVALID_SOCKET)
1666       closesocket(server);
1667     if (client0 != INVALID_SOCKET)
1668       closesocket(client0);
1669     if (client1 != INVALID_SOCKET)
1670       closesocket(client1);
1671 
1672     assert(err);
1673     return uv_translate_sys_error(err);
1674 }
1675