@@ -49,98 +49,28 @@ static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
4949}
5050
5151
52- /*
53- * Check if Windows version is 10.0.16299 (Windows 10, version 1709) or later.
54- */
55- static int uv__windows10_version1709 (void ) {
56- OSVERSIONINFOW os_info ;
57- if (!pRtlGetVersion )
58- return 0 ;
59- pRtlGetVersion (& os_info );
60- if (os_info .dwMajorVersion < 10 )
61- return 0 ;
62- if (os_info .dwMajorVersion > 10 )
63- return 1 ;
64- if (os_info .dwMinorVersion > 0 )
65- return 1 ;
66- return os_info .dwBuildNumber >= 16299 ;
67- }
68-
69-
70- static int uv__tcp_keepalive (uv_tcp_t * handle ,
71- SOCKET socket ,
72- int on ,
73- unsigned int idle ,
74- unsigned int intvl ,
75- unsigned int cnt ) {
52+ static int uv__tcp_keepalive (uv_tcp_t * handle , SOCKET socket , int enable , unsigned int delay ) {
7653 if (setsockopt (socket ,
7754 SOL_SOCKET ,
7855 SO_KEEPALIVE ,
79- (const char * )& on ,
80- sizeof on ) == -1 ) {
56+ (const char * )& enable ,
57+ sizeof enable ) == -1 ) {
8158 return WSAGetLastError ();
8259 }
8360
84- if (!on )
61+ if (!enable )
8562 return 0 ;
8663
87- if (idle < 1 || intvl < 1 || cnt < 1 )
64+ if (delay < 1 )
8865 return UV_EINVAL ;
8966
90- /* Windows 10, version 1709 (build 10.0.16299) and later require second units
91- * for TCP keepalive options. */
92- if (uv__windows10_version1709 ()) {
93- if (setsockopt (socket ,
94- IPPROTO_TCP ,
95- TCP_KEEPIDLE ,
96- (const char * )& idle ,
97- sizeof idle ) == -1 ) {
98- return WSAGetLastError ();
99- }
100-
101- if (setsockopt (socket ,
102- IPPROTO_TCP ,
103- TCP_KEEPINTVL ,
104- (const char * )& intvl ,
105- sizeof intvl ) == -1 ) {
106- return WSAGetLastError ();
107- }
108-
109- if (setsockopt (socket ,
110- IPPROTO_TCP ,
111- TCP_KEEPCNT ,
112- (const char * )& cnt ,
113- sizeof cnt ) == -1 ) {
114- return WSAGetLastError ();
115- }
116-
117- return 0 ;
118- }
119-
120- /* For those versions prior to Windows 10 version 1709,
121- * we fall back to SIO_KEEPALIVE_VALS that expects millisecond units.
122- * The SIO_KEEPALIVE_VALS IOCTL is supported on Windows 2000
123- * and later versions of the operating system. */
124- struct tcp_keepalive keepalive ;
125- keepalive .onoff = on ;
126- keepalive .keepalivetime = idle * 1000 ;
127- keepalive .keepaliveinterval = intvl * 1000 ;
128- /* On Windows Vista and later, the number of keep-alive probes
129- * (data retransmissions) is set to 10 and cannot be changed.
130- * On Windows Server 2003, Windows XP, and Windows 2000, the default setting
131- * for number of keep-alive probes is 5 and cannot be changed programmatically.
132- */
133- DWORD dummy ;
134- if (WSAIoctl (socket ,
135- SIO_KEEPALIVE_VALS ,
136- (LPVOID ) & keepalive ,
137- sizeof keepalive ,
138- NULL ,
139- 0 ,
140- & dummy ,
141- NULL ,
142- NULL ) == -1 )
67+ if (setsockopt (socket ,
68+ IPPROTO_TCP ,
69+ TCP_KEEPALIVE ,
70+ (const char * )& delay ,
71+ sizeof delay ) == -1 ) {
14372 return WSAGetLastError ();
73+ }
14474
14575 return 0 ;
14676}
@@ -202,7 +132,7 @@ static int uv__tcp_set_socket(uv_loop_t* loop,
202132
203133 /* TODO: Use stored delay. */
204134 if (handle -> flags & UV_HANDLE_TCP_KEEPALIVE ) {
205- err = uv__tcp_keepalive (handle , socket , 1 , 60 , 1 , 10 );
135+ err = uv__tcp_keepalive (handle , socket , 1 , 60 );
206136 if (err )
207137 return err ;
208138 }
@@ -819,6 +749,20 @@ static int uv__is_loopback(const struct sockaddr_storage* storage) {
819749 return 0 ;
820750}
821751
752+ // Check if Windows version is 10.0.16299 or later
753+ static int uv__is_fast_loopback_fail_supported (void ) {
754+ OSVERSIONINFOW os_info ;
755+ if (!pRtlGetVersion )
756+ return 0 ;
757+ pRtlGetVersion (& os_info );
758+ if (os_info .dwMajorVersion < 10 )
759+ return 0 ;
760+ if (os_info .dwMajorVersion > 10 )
761+ return 1 ;
762+ if (os_info .dwMinorVersion > 0 )
763+ return 1 ;
764+ return os_info .dwBuildNumber >= 16299 ;
765+ }
822766
823767static int uv__tcp_try_connect (uv_connect_t * req ,
824768 uv_tcp_t * handle ,
@@ -865,7 +809,7 @@ static int uv__tcp_try_connect(uv_connect_t* req,
865809 * is not reachable, instead of waiting for 2s. We do not care if this fails.
866810 * This only works on Windows version 10.0.16299 and later.
867811 */
868- if (uv__windows10_version1709 () && uv__is_loopback (& converted )) {
812+ if (uv__is_fast_loopback_fail_supported () && uv__is_loopback (& converted )) {
869813 memset (& retransmit_ioctl , 0 , sizeof (retransmit_ioctl ));
870814 retransmit_ioctl .Rtt = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS ;
871815 retransmit_ioctl .MaxSynRetransmissions = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS ;
@@ -1391,30 +1335,22 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
13911335}
13921336
13931337
1394- int uv_tcp_keepalive (uv_tcp_t * handle , int on , unsigned int idle ) {
1395- return uv_tcp_keepalive_ex (handle , on , idle , 1 , 10 );
1396- }
1397-
1398- int uv_tcp_keepalive_ex (uv_tcp_t * handle ,
1399- int on ,
1400- unsigned int idle ,
1401- unsigned int intvl ,
1402- unsigned int cnt ) {
1338+ int uv_tcp_keepalive (uv_tcp_t * handle , int enable , unsigned int delay ) {
14031339 int err ;
14041340
14051341 if (handle -> socket != INVALID_SOCKET ) {
1406- err = uv__tcp_keepalive (handle , handle -> socket , on , idle , intvl , cnt );
1342+ err = uv__tcp_keepalive (handle , handle -> socket , enable , delay );
14071343 if (err )
14081344 return uv_translate_sys_error (err );
14091345 }
14101346
1411- if (on ) {
1347+ if (enable ) {
14121348 handle -> flags |= UV_HANDLE_TCP_KEEPALIVE ;
14131349 } else {
14141350 handle -> flags &= ~UV_HANDLE_TCP_KEEPALIVE ;
14151351 }
14161352
1417- /* TODO: Store idle if handle->socket isn't created yet. */
1353+ /* TODO: Store delay if handle->socket isn't created yet. */
14181354
14191355 return 0 ;
14201356}
0 commit comments