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