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