@@ -27,6 +27,9 @@ extern "C" int initializeWinsockIfNecessary();
27
27
#include < stdarg.h>
28
28
#include < time.h>
29
29
#include < sys/time.h>
30
+ #if !defined(_WIN32)
31
+ #include < netinet/tcp.h>
32
+ #endif
30
33
#include < fcntl.h>
31
34
#define initializeWinsockIfNecessary () 1
32
35
#endif
@@ -217,8 +220,38 @@ Boolean makeSocketBlocking(int sock, unsigned writeTimeoutInMilliseconds) {
217
220
return result;
218
221
}
219
222
223
+ Boolean setSocketKeepAlive (int sock) {
224
+ #if defined(__WIN32__) || defined(_WIN32)
225
+ // How do we do this in Windows? For now, just make this a no-op in Windows:
226
+ #else
227
+ int const keepalive_enabled = 1 ;
228
+ if (setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive_enabled, sizeof keepalive_enabled) < 0 ) {
229
+ return False;
230
+ }
231
+
232
+ #ifdef TCP_KEEPIDLE
233
+ int const keepalive_time = 180 ;
234
+ if (setsockopt (sock, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepalive_time, sizeof keepalive_time) < 0 ) {
235
+ return False;
236
+ }
237
+ #endif
238
+
239
+ int const keepalive_count = 5 ;
240
+ if (setsockopt (sock, IPPROTO_TCP, TCP_KEEPCNT, (void *)&keepalive_count, sizeof keepalive_count) < 0 ) {
241
+ return False;
242
+ }
243
+
244
+ int const keepalive_interval = 20 ;
245
+ if (setsockopt (sock, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepalive_interval, sizeof keepalive_interval) < 0 ) {
246
+ return False;
247
+ }
248
+ #endif
249
+
250
+ return True;
251
+ }
252
+
220
253
int setupStreamSocket (UsageEnvironment& env,
221
- Port port, Boolean makeNonBlocking) {
254
+ Port port, Boolean makeNonBlocking, Boolean setKeepAlive ) {
222
255
if (!initializeWinsockIfNecessary ()) {
223
256
socketErr (env, " Failed to initialize 'winsock': " );
224
257
return -1 ;
@@ -284,6 +317,16 @@ int setupStreamSocket(UsageEnvironment& env,
284
317
}
285
318
}
286
319
320
+ // Set the keep alive mechanism for the TCP socket, to avoid "ghost sockets"
321
+ // that remain after an interrupted communication.
322
+ if (setKeepAlive) {
323
+ if (!setSocketKeepAlive (newSocket)) {
324
+ socketErr (env, " failed to set keep alive: " );
325
+ closeSocket (newSocket);
326
+ return -1 ;
327
+ }
328
+ }
329
+
287
330
return newSocket;
288
331
}
289
332
0 commit comments