Onde estão meus TIME_WAITs no Mac OS X?

9

Não há TIME_WAITno Mac OS X

Normalmente, quando uma conexão TCP é fechada, o soquete do lado onde close()é chamado primeiro é deixado no TIME_WAITestado.

Quando um dos pares é uma máquina Mac OS X (Lion), nenhum TIME_WAITé listado netstat -anno Mac se close()for chamado primeiro no lado do Mac. No entanto, parece que o soquete está realmente no TIME_WAITestado, porque tentar chamar listen()novamente (sem usar a opção de soquete SO_REUSEADDR) causa listen()falha.

A espera de 2 * MSL (Vida útil máxima do segmento, que é de 15 segundos no Mac OS X Lion, conforme relatado por sysctl net.inet.tcp.msl) limpa o TIME_WAITestado e listen()pode ser chamado novamente sem erro.

Por que não consigo ver o soquete TIME_WAIT?

Teste

Aqui estão dois programas de teste simples em Python.

Servidor

#!/usr/bin/env python

import socket

HOST = ''
PORT = 50007
l = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
l.bind((HOST, PORT))
l.listen(1)
print("Listening on %d" % PORT)
(s, _) = l.accept()
print("Connected")
raw_input("Press <enter> to close...")
l.close()
s.close()
print("Closed")

Cliente

#!/usr/bin/env python

import socket
import sys

HOST = sys.argv[1]
PORT = 50007

print("Opening connection to server")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
raw_input("Press <enter> to close...")
s.close()
print("Closed")

Ao executar o servidor e o cliente em duas máquinas Linux diferentes, o ponto que pressiona <enter>para ligar close()primeiro obtém o TIME_WAITesperado:

$ ./server-timewait.py 
Listening on 50007
Connected
Press <enter> to close...
Closed
$ netstat -an | grep 50007
tcp        0      0 172.16.185.219:50007    172.16.185.42:49818     TIME_WAIT  
$ 

Quando um dos colegas é um Mac (executando o OS X Lion), nunca vejo um TIME_WAITao executar netstat -an | grep 50007depois de fechar o Mac pela primeira vez.

mgd
fonte
Boa pergunta. Vendo a mesma coisa a mim mesmo, e não ver quaisquer opções para netstat para incluí-los ...
natevw
2
FWIW, sudo lsof -i -Pnão mostra o status TIME_WAIT para processos que já foram encerrados.
Natevw 30/07/2014
@natevw Feliz em saber que não estou sozinha. :-)
mgd 30/07

Respostas:

2

Este relatório de bug afirma que o problema está na implementação do netstat . O código anexado ao relatório de erros mostra os soquetes no estado TIME_WAIT corretamente. Você precisa remover as seguintes linhas

if (lip == INADDR_LOCALHOST ||
  lip == INADDR_ANY
  ) { continue; }

para mostrar os soquetes vinculados ao localhost.

neverov
fonte
0

Esta não é uma resposta, mas talvez alguém possa descobrir mais sobre isso.

tcpdump -i lo0 -vv port 50007

## Press Enter at the server window

# Server send a FIN (note the flag)
23:33:04.283768 IP (tos 0x0, ttl 64, id 4134, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->2c9c)!)
    localhost.50007 > localhost.56030: Flags [F.], cksum 0xfe28 (incorrect -> 0xeff9), seq 1, ack 1, win 9186, options [nop,nop,TS val 432165676 ecr 432157913], length 0

# Client send back ACK
23:33:04.283803 IP (tos 0x0, ttl 64, id 44906, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->8d57)!)
    localhost.56030 > localhost.50007: Flags [.], cksum 0xfe28 (incorrect -> 0xd1a6), seq 1, ack 2, win 9186, options [nop,nop,TS val 432165676 ecr 432165676], length 0

# Server confirm the ACK is received
23:33:04.283812 IP (tos 0x0, ttl 64, id 18284, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->f555)!)
    localhost.50007 > localhost.56030: Flags [.], cksum 0xfe28 (incorrect -> 0xd1a6), seq 2, ack 1, win 9186, options [nop,nop,TS val 432165676 ecr 432165676], length 0

## After this point, the server process is actually exit but client still running.
## It's strange that re-run server script gives "OSError: [Errno 48] Address already in use"
## and netstat shows this connection is in CLOSE_WAIT status

## Press Enter at the client window

# Client send a FIN to server
23:33:09.731728 IP (tos 0x0, ttl 64, id 51478, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->73ab)!)
    localhost.56030 > localhost.50007: Flags [F.], cksum 0xfe28 (incorrect -> 0xbcb6), seq 1, ack 2, win 9186, options [nop,nop,TS val 432171035 ecr 432165676], length 0

# WTH!? Who send back this packet? The server process is closed!
23:33:09.731764 IP (tos 0x0, ttl 64, id 18754, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->f37f)!)
    localhost.50007 > localhost.56030: Flags [.], cksum 0xfe28 (incorrect -> 0xa7c7), seq 2, ack 2, win 9186, options [nop,nop,TS val 432171035 ecr 432171035], length 0
yegle
fonte
"WTH !? Quem envia este pacote de volta? O processo do servidor está fechado!" Parece ter sido enviado pelo servidor que está no estado TIME_WAIT, porque é a parte que envia o primeiro FIN. Mesmo que o processo do servidor tenha sido encerrado, a pilha TCP mantém o estado da conexão para enviar o último ACK.
neverov 11/02