Quando / como o Linux decide fechar um socket no kill de aplicativos?

3

Eu tenho um processo de servidor e um processo cliente em execução na mesma máquina Linux.

Às vezes, quando eu kill -9 o cliente, vejo com tcpdump que uma mensagem FIN, ACK é enviada. É claro que o cliente morto não poderia ter feito isso porque ele está morto brutalmente com SIGKILL . Então eu acho que o Linux OS lida com o fechamento da conexão.

Às vezes, não vejo nenhuma conexão próxima e a conexão permanece "ESTABLISHED" (por netstat ).

Eu sempre vejo uma conexão sendo fechada em Linux ubuntu 4.4.0-53-generic .
Às vezes vejo uma conexão sendo fechada em Linux 3.13.11 (kernel puro, não Ubuntu).

Minhas perguntas são:

  1. O Linux lida com conexões de fechamento?
    1.1 Em SIGKILL ?
    1.2. Quando o aplicativo é fechado corretamente, mas não chama close() ?
  2. Essa funcionalidade mudou entre as versões do kernel 3.13.11 e 4.4.0 ? O Ubuntu tem alguma coisa com isso?
  3. E se esses dois processos não estivessem na mesma máquina Linux: ele se comportaria da mesma maneira?
  4. Por que a conexão às vezes permanece "ESTABELECIDA"?
  5. Estou ciente das opções de% TCPkeepalive socket. Se o Linux realmente lida com o fechamento da conexão. Por que eles existem? Somente se o pacote FIN, ACK cair?
por hudac 16.08.2017 / 23:17

1 resposta

1

Uma questão ampla. Talvez alguém possa analisar sua questão sobre a pilha TCP do kernel entre versões específicas do kernel.

Algumas respostas gerais:

Do lado do cliente

  1. No caso de um sinal SIGKILL , o kernel encerra a execução do programa e, entre outras coisas, fecha os descritores de arquivos abertos do processo. Os soquetes TCP são tratados de forma um pouco diferente pelo kernel do que os arquivos regulares, pois precisam ser liberados e passar pelo processo de shudown do TCP.

    A diferença em um 'FIN, ACK' imediato do cliente e um desligamento de soquete mais longo pode depender do estado em que a conexão TCP do cliente estava quando o aplicativo cliente foi finalizado. Mas geralmente o kernel fechará os sockets abertos da aplicação.

Do lado do servidor

  1. Um servidor nem sempre sabe quando um cliente se desconecta. A maneira mais confiável de determinar se um cliente foi desligado é tentar uma leitura do soquete que retorna um EOF.

    O TCP foi projetado para ser resiliente à latência de conexão e a falhas intermitentes. Isso também se traduz em alguns desafios que detectam desconexões de maneira confiável, caso o handshaking de desconexão de FIN, ACK 4 não ocorra.

Resumo

O que você pode estar vendo em um kill -9 do cliente é o servidor que entra no CLOSE_WAIT do estado do TCP, onde está aguardando um tempo limite do TCP. Isso pode demorar um pouco. Mesmo que o cliente tenha sumido, se o kernel não mantivesse o handshaking de desconexão TCP, o servidor teria que expirar.

Se eu lembrar, isso pode levar vários segundos e é provável que você ainda veja ESTABLISHED devido à execução do cliente e do servidor no mesmo host.

    
por 17.08.2017 / 00:01