Pular para o conteúdo principal

Às vezes a netstat mostrará uma tomada que parece estar presa. A aplicação remota foi encerrada, às vezes até mesmo a aplicação OpenVOS foi encerrada, mas a netstat ainda mostra o soquete. Este artigo explicará por que isto acontece e o que você pode fazer a respeito.

Uma breve introdução aos estados TCP

Se você pesquisar no Google "tcp state diagram" você encontrará uma infinidade de imagens, algumas mal legíveis, outras bastante legíveis. A Wikimedia tem um código de cores muito bonito (http://commons.wikimedia.org/wiki/File:TCP_state_diagram.png). O TCP RFC (793) (http://www.rfc-editor.org/rfc/rfc793.txt) tem um diagrama de arte ASCII e, é claro, explica os estados em detalhes.

As tomadas podem ficar presas quando estão esperando que a aplicação local ou o host remoto faça algo. Há três estados onde isto ocorre. No estado FIN_WAIT_2, o soquete está esperando que o host remoto feche a conexão. No estado FECHADO_WAIT está esperando que a aplicação local feche o soquete e no estado ESTABELECIDO está esperando que o host remoto abra sua janela de envio, ou que a aplicação local envie alguma coisa. Se a pilha TCP local tiver enviado dados e estiver aguardando que o host remoto reconheça que não pode ficar preso, ele eventualmente irá parar, sinalizar um erro para a aplicação local e fechar o soquete.

FIN_WAIT_2 estado

Este é talvez o caso mais comum de tomada presa que é chamado de CAC. A aplicação local fechou o soquete e pode ter terminado. A razão típica para que as tomadas fiquem presas neste estado é que a aplicação remota é pendurada e não lê sua tomada.

A definição do parâmetro STCP finwait2 para alguns N > 0 fechará as tomadas depois de terem estado no FIN_WAIT_2 por N segundos. A partir das versões 14.7.2bg, 14.7.tl1, 15.2.1aa, 15.2.tel.af, 15.3.0bd, 15.3.tel.ag, 16.2.1al, 17.0.0ai e 17.1 o valor padrão é 1200, antes disso o padrão era 0 (portanto, se você quiser que os soquetes tenham um tempo limite, você mesmo terá que configurá-lo). Você pode ver o valor atual com a solicitação list_stcp_params analyze_system, você pode alterar o valor com a solicitação set_stcp_param analyze_system. Veja o manual Análise de Sistema OpenVOS (R073), disponível em http://stratadoc.stratus.com, para documentação sobre estas solicitações.

Estado FECHADO_WAIT

Este é o próximo estado de soquete preso mais comum. Os soquetes em estado FECHADO_WAIT estão esperando a aplicação local para fechar o soquete. A razão típica para um soquete permanecer neste estado é que a aplicação não está mais lendo o soquete. A maneira mais fácil de fechar o soquete é terminar a aplicação local.

Se o término da aplicação local não for uma opção, a única coisa que você pode fazer é criar um pacote com o conjunto de bandeiras RST (reset). Isto requer que você saiba os números seqüenciais usados pelo soquete (disponíveis usando o dump_onetcb analyze_system request) e tenha um utilitário em outro host na sub-rede local que possa construir e enviar pacotes IP personalizados. Estes utilitários estão disponíveis para sistemas Windows e Linux.

Estado ESTABELECIDO

Já que na maioria das vezes a netstat mostra soquetes no estado ESTABELECIDO, como você pode saber quando o soquete está preso? Se você tiver um relatório de que o host remoto falhou ou a rede entre o host local e o remoto falhou por mais de 10 minutos e a aplicação local está esperando que o remoto lhe envie algo, você pode ter certeza de que o soquete está preso. Neste caso o valor da fila de envio (o número à esquerda imediata do endereço IP local) informado pela netstat será 0. Por outro lado, se o valor da fila de envio for maior que 0 e permanecer lá, você poderá ter o caso do host remoto anunciando uma janela zero.

No primeiro caso, a menos que o keep-alive seja ligado, o soquete permanecerá no estado ESTABELECIDO até que a aplicação local seja encerrada. Se o keep-alive estiver ligado, então após o término do timer keep-alive, a STCP enviará uma sonda keep-alive. Se a sonda ficar sem resposta, ela será retransmitida, mas após alguns minutos e várias retransmissões, a conexão será terminada. Por padrão, a interface tem o keep-alive configurado, mas também por padrão não tem soquetes. Para definir o keep-alive em um soquete, a aplicação deve usar a chamada de função setsockopt. Veja o manual OpenVOS STREAMS TCP/IP Programming (R420), também disponível em http://stratadoc.stratus.com, para detalhes. O tempo padrão de keep-alive é de 2 horas; isso significa que a primeira sonda keep-alive é transmitida 2 horas após o último segmento TCP ser recebido do host remoto, portanto você deve ser paciente. Para aqueles que não são tão pacientes, você pode ajustar o tempo "keep-alive" e também o tempo entre as sondas e o número de sondas com o pedido de parc parc parc parc_setcp dentro do sistema de análise. Não recomendo a alteração destes parâmetros sem uma análise detalhada.

Se o soquete não tiver o conjunto keep-alive, a única opção simples é encerrar a aplicação que possui o soquete. Se esta não for uma opção é possível fechar o soquete enviando-lhe um segmento com o conjunto de bandeiras RST.

Para confirmar o segundo caso, verifique o valor de sndws exibido pela solicitação dump_onetcb analyze_system. Um valor 0 indica uma janela fechada. Você também pode executar o packet_monitor para rastrear a conexão e verificar o valor da janela no cabeçalho TCP em segmentos a partir do host remoto. Um valor de "n.a." indica 0.

Quero enfatizar que esta pode ser uma condição recuperável. As aplicações às vezes se atrasam e a pilha TCP fecha a janela, quando a aplicação fica presa à pilha, abre a janela. Entretanto, na maioria dos casos, acho que é seguro assumir que se a aplicação não se recuperou após alguns minutos, não o fará. A exceção pode ser algo como uma impressora que está sem papel. Um soquete neste estado pode permanecer neste estado mesmo que a aplicação VOS que o criou termine.

Estes soquetes podem ser limpos ajustando tcp_zerowin_abort_intervalo_intervalo para algum N > 0. Os soquetes serão limpos N segundos após o próximo segmento TCP com janela zero ser recebido. As sondas de janela são enviadas a cada 100 segundos para confirmar que a janela de recepção do host remoto ainda está fechada, portanto, na pior das hipóteses, uma resposta será recebida dentro de 100 segundos. O valor padrão de tcp_zerowin_abort_intervalo_intervalo é zero e sugiro que ele permaneça em 0 a menos que você precise limpar um soquete. Nesse momento, sugiro que o valor seja pequeno, digamos 10 segundos, e uma vez que o soquete for limpo, redefinindo-o para 0. Acho que isto reduz o risco de limpar soquetes que são recuperáveis.

Para definir este valor, você deve usar o pedido de set_longword no sistema de análise, então lembre-se que N estará em hexadecimal. Por exemplo, para configurá-lo para 10, a solicitação seria:
set_longword tcp_zerowin_abort_interval$ a

© 2024 Stratus Technologies.