LP#1042850: Add TCP-level keepalive
authorMike Rylander <mrylander@gmail.com>
Mon, 4 Aug 2014 13:26:56 +0000 (09:26 -0400)
committerBill Erickson <berick@esilibrary.com>
Thu, 7 Aug 2014 18:05:44 +0000 (14:05 -0400)
Some client TCP stacks fail to actually close down their sockets
all the way, leading to a pile up of stale backends that can never
go away.

So, we will use Linux's TCP_KEEPALIVE tuning capabilities to probe
the connection on a regular basis.  This should detect the half-
closed situation and let the backend shut itself down.

Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Bill Erickson <berick@esilibrary.com>
SIPServer.pm

index 4ea82c5..fa78be9 100755 (executable)
@@ -26,7 +26,7 @@ use Sys::Syslog qw(syslog);
 use Net::Server::PreFork;
 use Net::Server::Proto;
 use IO::Socket::INET;
-use Socket qw(:crlf);
+use Socket qw(:crlf SOL_SOCKET SO_KEEPALIVE IPPROTO_TCP TCP_KEEPALIVE);
 use Data::Dumper;              # For debugging
 require UNIVERSAL::require;
 
@@ -113,6 +113,14 @@ sub process_request {
     my ($sockaddr, $port, $proto);
     my $transport;
 
+    eval { # If it fails ... oh well
+        use Socket::Linux qw(TCP_KEEPINTVL TCP_KEEPIDLE TCP_KEEPCNT);
+        setsockopt($self->{server}->{client}, SOL_SOCKET, SO_KEEPALIVE, 1);
+        setsockopt($self->{server}->{client}, IPPROTO_TCP, TCP_KEEPALIVE, 1);
+        setsockopt($self->{server}->{client}, IPPROTO_TCP, TCP_KEEPIDLE, 120);
+        setsockopt($self->{server}->{client}, IPPROTO_TCP, TCP_KEEPINTVL, 10);
+    };
+
     $self->{account} = undef; # New connection, no need to keep login info
     $self->{config} = $config;