¿Dónde están mis TIME_WAITs en Mac OS X?


9

No TIME_WAITs en Mac OS X

Normalmente, cuando se cierra una conexión TCP, el socket en el lado donde close()se llama primero se deja en el TIME_WAITestado.

Cuando uno de los pares es una máquina Mac OS X (Lion), no TIME_WAITaparece netstat -anen la lista de Mac si close()se llama primero en el lado de Mac. Sin embargo, parece que el socket está realmente en TIME_WAITestado, porque intentar llamar listen()nuevamente (sin usar la opción de socket SO_REUSEADDR) hace listen()que falle.

Esperar 2 * MSL (Duración máxima del segmento, que es de 15 segundos en Mac OS X Lion, según lo informado por sysctl net.inet.tcp.msl) borra el TIME_WAITestado y se listen()puede volver a llamar sin error.

¿Por qué no puedo ver el zócalo TIME_WAIT?

Pruebas

Aquí hay dos programas de prueba simples en 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")

Al ejecutar tanto el servidor como el cliente en dos máquinas Linux diferentes, el par que presiona <enter>para llamar close()primero obtiene el resultado 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  
$ 

Cuando uno de los pares es una Mac (con OS X Lion) nunca veo una TIME_WAITcuando se ejecuta netstat -an | grep 50007después de cerrar primero en la Mac.


Buena pregunta. Al ver lo mismo y no ver ninguna opción para netstat para incluirlos ...
natevw

2
FWIW, sudo lsof -i -Ptampoco muestra el estado TIME_WAIT para procesos que ya han salido.
natevw

@natevw Feliz de saber que no estoy solo. :-)
mgd

Respuestas:


2

Este informe de error afirma que el problema está en la implementación de netstat . El código adjunto al informe de error muestra los sockets en el estado TIME_WAIT correctamente. Debes eliminar las siguientes líneas

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

para que muestre sockets vinculados a localhost.


0

Esta no es una respuesta, pero tal vez alguien pueda extraer más de esto.

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

"¡¿QUÉ ?! ¿Quién envió este paquete? ¡El proceso del servidor está cerrado!" Parece ser enviado por el servidor que está en estado TIME_WAIT, porque es la parte que envía el primer FIN. Aunque el proceso del servidor finalizó, la pila TCP mantiene el estado de la conexión para enviar el último ACK.
neverov
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.