From cb04eb8840b3102f412a46471eb1de2a6cc65ff1 Mon Sep 17 00:00:00 2001 From: Eric House Date: Wed, 21 Dec 2011 18:18:30 -0800 Subject: [PATCH] finally got the socket leak: use keepalive ioctl to detect sockets whose other ends have gone down without closing properly. --- xwords4/relay/xwrelay.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/xwords4/relay/xwrelay.cpp b/xwords4/relay/xwrelay.cpp index aae3fcd8c..2b920a14f 100644 --- a/xwords4/relay/xwrelay.cpp +++ b/xwords4/relay/xwrelay.cpp @@ -1002,6 +1002,38 @@ set_timeouts( int sock ) } } +static void +enable_keepalive( int sock ) +{ + int optval = 1; + if ( 0 > setsockopt( sock, SOL_SOCKET, SO_KEEPALIVE, + &optval, sizeof( optval ) ) ) { + logf( XW_LOGERROR, "setsockopt(SO_KEEPALIVE)=>%d (%s)", errno, + strerror(errno) ); + assert( 0 ); + } + /* + The above will kill sockets, eventually, whose remote ends have died + without notifying us. (Duplicate by pulling a phone's battery while it + has an open connection.) It'll take nearly three hours, however. The + info below appears to allow for significantly shortening the time, + though at the expense of greater network traffic. I'm going to let it + run this way before bothering with anything more. + + from http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/ + + "There are also three other socket options you can set for keepalive + when you write your application. They all use the SOL_TCP level instead + of SOL_SOCKET, and they override system-wide variables only for the + current socket. If you read without writing first, the current + system-wide parameters will be returned." + + * TCP_KEEPCNT: overrides tcp_keepalive_probes + * TCP_KEEPIDLE: overrides tcp_keepalive_time + * TCP_KEEPINTVL: overrides tcp_keepalive_intvl + */ +} + int main( int argc, char** argv ) { @@ -1312,6 +1344,8 @@ main( int argc, char** argv ) /* Set timeout so send and recv won't block forever */ set_timeouts( newSock ); + + enable_keepalive( newSock ); logf( XW_LOGINFO, "accepting connection from %s on socket %d",