8

Does anyone know if Linux supports keep-alive socket options on an outgoing connection?

I made an outgoing connection with keep-alive options but netstat --timers shows off (I'm assuming timers are off):

tcp 0 0 localhost.localdomain:44307 172.16.0.15:2717 ESTABLISHED off (0.00/0/0)

Incoming connections with the same socket options applied show:

tcp 0 0 172.16.0.3:8585 localhost.localdomain:21527 ESTABLISHED keepalive (29.26/0/0)

I wish I could see socket options but neither ss or lsof will show me them.

James Hartig
  • 131
  • 1
  • 1
  • 5

2 Answers2

7

First you need to make sure that TCP keepalive is enabled on your system. You can check the default settings like this:

# sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_probes net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

Then make sure you're setting it properly in your code. It should look something like this:

int optval = 1;
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) {
    perror("setsockopt()");
    close(s);
    exit(EXIT_FAILURE);
}

On my system when I use the above code to set SO_KEEPALIVE on both sides I see:

tcp        0      0 127.0.0.1:48591         127.0.0.1:5555          ESTABLISHED keepalive (6958.37/0/0)
tcp        0      0 127.0.0.1:5555          127.0.0.1:48591         ESTABLISHED keepalive (6958.37/0/0)

And then I verified with wireshark that the keepalive NOP was being sent.

More details can be found in the TCP Keepalive HOWTO.

aculich
  • 3,520
  • 1
  • 25
  • 33
  • Thanks for the info, but I had already had those set and I'm setting it the exact same way as you, i'm just not setting keepalive in netstat. – James Hartig Dec 13 '11 at 21:58
  • 1
    In that case, post more info about your system and the source code (or a simplified test case) so I can try to reproduce the problem, otherwise there's not a lot to go on here to debug. – aculich Dec 14 '11 at 11:20
  • @aculich is right, if you have set keepalive in the system, it's your application that doesn't use it properly. I advice to read the TCP Keepalive HOWTO as suggested by aculich or to post the source code of the application or either try to execute an lsof to see what happens – tmow Dec 16 '11 at 16:29
0

client-sysctl-setting:

sudo /sbin/sysctl -a|grep keep
net.ipv4.tcp_keepalive_time = 20
net.ipv4.tcp_keepalive_probes = 1
net.ipv4.tcp_keepalive_intvl = 1

client keep tcpdump:

sudo /usr/sbin/tcpdump  -nn -vv -i bond0 tcp and host 10.201.126.72 and port 8001
tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes

but not any package capture , which means tcp_keepalive_time doesn't work

Dennis Nolte
  • 2,848
  • 4
  • 26
  • 36