@@ -149,13 +149,7 @@ static void nosigpipe(struct Curl_cfilter *cf,
149149#define nosigpipe (x ,y ,z ) Curl_nop_stmt
150150#endif
151151
152- #if defined(USE_WINSOCK ) && \
153- defined(TCP_KEEPIDLE ) && defined(TCP_KEEPINTVL ) && defined(TCP_KEEPCNT )
154- /* Win 10, v 1709 (10.0.16299) and later can use SetSockOpt TCP_KEEP____
155- * so should use seconds */
156- #define CURL_WINSOCK_KEEP_SSO
157- #define KEEPALIVE_FACTOR (x )
158- #elif defined(USE_WINSOCK ) || \
152+ #if defined(USE_WINSOCK ) || \
159153 (defined(__sun ) && !defined(TCP_KEEPIDLE )) || \
160154 (defined(__DragonFly__ ) && __DragonFly_version < 500702 ) || \
161155 (defined(_WIN32 ) && !defined(TCP_KEEPIDLE ))
@@ -166,17 +160,6 @@ static void nosigpipe(struct Curl_cfilter *cf,
166160#define KEEPALIVE_FACTOR (x )
167161#endif
168162
169- /* Offered by mingw-w64 and MS SDK. Latter only when targeting Win7+. */
170- #if defined(USE_WINSOCK ) && !defined(SIO_KEEPALIVE_VALS )
171- #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
172-
173- struct tcp_keepalive {
174- u_long onoff ;
175- u_long keepalivetime ;
176- u_long keepaliveinterval ;
177- };
178- #endif
179-
180163static void
181164tcpkeepalive (struct Curl_cfilter * cf ,
182165 struct Curl_easy * data ,
@@ -192,49 +175,64 @@ tcpkeepalive(struct Curl_cfilter *cf,
192175 sockfd , SOCKERRNO );
193176 }
194177 else {
195- #ifdef SIO_KEEPALIVE_VALS /* Windows */
196- /* Windows 10, version 1709 (10.0.16299) and later versions */
197- #ifdef CURL_WINSOCK_KEEP_SSO
198- optval = curlx_sltosi (data -> set .tcp_keepidle );
199- KEEPALIVE_FACTOR (optval );
200- if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPIDLE ,
201- (const char * )& optval , sizeof (optval )) < 0 ) {
202- CURL_TRC_CF (data , cf , "Failed to set TCP_KEEPIDLE on fd "
203- "%" FMT_SOCKET_T ": errno %d" ,
204- sockfd , SOCKERRNO );
205- }
206- optval = curlx_sltosi (data -> set .tcp_keepintvl );
207- KEEPALIVE_FACTOR (optval );
208- if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPINTVL ,
209- (const char * )& optval , sizeof (optval )) < 0 ) {
210- CURL_TRC_CF (data , cf , "Failed to set TCP_KEEPINTVL on fd "
211- "%" FMT_SOCKET_T ": errno %d" ,
212- sockfd , SOCKERRNO );
213- }
214- optval = curlx_sltosi (data -> set .tcp_keepcnt );
215- if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPCNT ,
216- (const char * )& optval , sizeof (optval )) < 0 ) {
217- CURL_TRC_CF (data , cf , "Failed to set TCP_KEEPCNT on fd "
218- "%" FMT_SOCKET_T ": errno %d" ,
219- sockfd , SOCKERRNO );
178+ #ifdef USE_WINSOCK
179+ /* Offered by mingw-w64 v12+. MS SDK ~10+/~VS2017+. */
180+ #if defined(TCP_KEEPIDLE ) && defined(TCP_KEEPINTVL ) && defined(TCP_KEEPCNT )
181+ /* Windows 10, version 1709 (10.0.16299) and later versions can use
182+ setsockopt() TCP_KEEP*. Older versions return with failure. */
183+ if (curlx_verify_windows_version (10 , 0 , 16299 , PLATFORM_WINNT ,
184+ VERSION_GREATER_THAN_EQUAL )) {
185+ CURL_TRC_CF (data , cf , "Set TCP_KEEP* on fd=%" FMT_SOCKET_T , sockfd );
186+ optval = curlx_sltosi (data -> set .tcp_keepidle );
187+ if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPIDLE ,
188+ (const char * )& optval , sizeof (optval )) < 0 ) {
189+ CURL_TRC_CF (data , cf , "Failed to set TCP_KEEPIDLE on fd "
190+ "%" FMT_SOCKET_T ": errno %d" ,
191+ sockfd , SOCKERRNO );
192+ }
193+ optval = curlx_sltosi (data -> set .tcp_keepintvl );
194+ if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPINTVL ,
195+ (const char * )& optval , sizeof (optval )) < 0 ) {
196+ CURL_TRC_CF (data , cf , "Failed to set TCP_KEEPINTVL on fd "
197+ "%" FMT_SOCKET_T ": errno %d" ,
198+ sockfd , SOCKERRNO );
199+ }
200+ optval = curlx_sltosi (data -> set .tcp_keepcnt );
201+ if (setsockopt (sockfd , IPPROTO_TCP , TCP_KEEPCNT ,
202+ (const char * )& optval , sizeof (optval )) < 0 ) {
203+ CURL_TRC_CF (data , cf , "Failed to set TCP_KEEPCNT on fd "
204+ "%" FMT_SOCKET_T ": errno %d" ,
205+ sockfd , SOCKERRNO );
206+ }
220207 }
221- #else /* Windows < 10.0.16299 */
222- struct tcp_keepalive vals ;
223- DWORD dummy ;
224- vals .onoff = 1 ;
225- optval = curlx_sltosi (data -> set .tcp_keepidle );
226- KEEPALIVE_FACTOR (optval );
227- vals .keepalivetime = (u_long )optval ;
228- optval = curlx_sltosi (data -> set .tcp_keepintvl );
229- KEEPALIVE_FACTOR (optval );
230- vals .keepaliveinterval = (u_long )optval ;
231- if (WSAIoctl (sockfd , SIO_KEEPALIVE_VALS , (LPVOID ) & vals , sizeof (vals ),
232- NULL , 0 , & dummy , NULL , NULL ) != 0 ) {
233- CURL_TRC_CF (data , cf , "Failed to set SIO_KEEPALIVE_VALS on fd "
234- "%" FMT_SOCKET_T ": errno %d" , sockfd , SOCKERRNO );
208+ else
209+ #endif /* TCP_KEEPIDLE && TCP_KEEPINTVL && TCP_KEEPCNT */
210+ {
211+ /* Offered by mingw-w64 and MS SDK. Latter only when targeting Win7+. */
212+ #ifndef SIO_KEEPALIVE_VALS
213+ #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
214+ struct tcp_keepalive {
215+ u_long onoff ;
216+ u_long keepalivetime ;
217+ u_long keepaliveinterval ;
218+ };
219+ #endif
220+ struct tcp_keepalive vals ;
221+ DWORD dummy ;
222+ vals .onoff = 1 ;
223+ optval = curlx_sltosi (data -> set .tcp_keepidle );
224+ KEEPALIVE_FACTOR (optval );
225+ vals .keepalivetime = (u_long )optval ;
226+ optval = curlx_sltosi (data -> set .tcp_keepintvl );
227+ KEEPALIVE_FACTOR (optval );
228+ vals .keepaliveinterval = (u_long )optval ;
229+ if (WSAIoctl (sockfd , SIO_KEEPALIVE_VALS , (LPVOID )& vals , sizeof (vals ),
230+ NULL , 0 , & dummy , NULL , NULL ) != 0 ) {
231+ CURL_TRC_CF (data , cf , "Failed to set SIO_KEEPALIVE_VALS on fd "
232+ "%" FMT_SOCKET_T ": errno %d" , sockfd , SOCKERRNO );
233+ }
235234 }
236- #endif
237- #else /* !Windows */
235+ #else /* !USE_WINSOCK */
238236#ifdef TCP_KEEPIDLE
239237 optval = curlx_sltosi (data -> set .tcp_keepidle );
240238 KEEPALIVE_FACTOR (optval );
@@ -303,7 +301,7 @@ tcpkeepalive(struct Curl_cfilter *cf,
303301 "%" FMT_SOCKET_T ": errno %d" , sockfd , SOCKERRNO );
304302 }
305303#endif
306- #endif
304+ #endif /* USE_WINSOCK */
307305 }
308306}
309307
0 commit comments