Opções keep-alive não funcionando no Linux para uma conexão de saída

8

Alguém sabe se o Linux suporta opções de soquete keep-alive em uma conexão de saída?

Fiz uma conexão de saída com as opções keep-alive, mas o netstat --timers é exibido (suponho que os temporizadores estejam desativados):

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

As conexões de entrada com as mesmas opções de soquete aplicadas mostram:

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

Eu gostaria de poder ver opções de soquete, mas nem ss nem lsof me mostrarão.

James Hartig
fonte

Respostas:

7

Primeiro, você precisa garantir que o TCP keepalive esteja ativado no seu sistema. Você pode verificar as configurações padrão como esta:

# 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

Em seguida, verifique se está configurando corretamente no seu código. Deve ser algo como isto:

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

No meu sistema, quando uso o código acima para definir SO_KEEPALIVE nos dois lados, vejo:

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)

E então eu verifiquei com o wireshark que o keepalive NOPestava sendo enviado.

Mais detalhes podem ser encontrados no HOWTO TCP Keepalive .

aculich
fonte
Obrigado pela informação, mas eu já tinha as definidas e estou definindo exatamente da mesma maneira que você, mas não estou definindo keepalive no netstat.
precisa
1
Nesse caso, poste mais informações sobre seu sistema e o código-fonte (ou um caso de teste simplificado) para que eu possa tentar reproduzir o problema; caso contrário, não há muito o que fazer aqui para depurar.
Aculich
@aculich está certo, se você configurou o keepalive no sistema, é o seu aplicativo que não o usa corretamente. Conselho que eu ler o TCP Keepalive HOWTO como sugerido por aculich ou para publicar o código-fonte do aplicativo ou quer tentar executar uma lsof para ver o que acontece
tmow
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

cliente mantenha 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

mas nenhuma captura de pacote, o que significa que tcp_keepalive_time não funciona

user393527
fonte