Dove sono i miei TIME_WAIT su Mac OS X?


9

No TIME_WAITsu Mac OS X.

Normalmente, quando una connessione TCP viene chiusa, il socket sul lato in cui close()viene chiamato per primo viene lasciato nello TIME_WAITstato.

Quando uno dei peer è una macchina Mac OS X (Lion), no TIME_WAITviene elencato netstat -ansul Mac se close()viene chiamato per primo sul lato Mac. Tuttavia, sembra che il socket sia effettivamente nello TIME_WAITstato, perché il tentativo di richiamare listen()nuovamente (senza utilizzare l'opzione socket SO_REUSEADDR) causa un listen()errore.

Attendere 2 * MSL (durata massima del segmento, che è di 15 secondi su Mac OS X Lion come riportato da sysctl net.inet.tcp.msl), cancella lo TIME_WAITstato e listen()può essere richiamato senza errori.

Perché non riesco a vedere la presa TIME_WAIT?

analisi

Ecco due semplici programmi di test in Python.

server

#!/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")

Quando si eseguono sia il server che il client su due diverse macchine Linux, il peer che preme <enter>per chiamare close()ottiene per primo TIME_WAITcome previsto:

$ ./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 uno dei peer è un Mac (con OS X Lion) non vedo mai un TIME_WAITquando si esegue netstat -an | grep 50007dopo aver chiuso per primo sul Mac.


Buona domanda. Vedere io stesso la stessa cosa e non vedere alcuna opzione per netstat di includerli ...
natevw,

2
FWIW, sudo lsof -i -Pnon mostra lo stato TIME_WAIT per i processi che sono già usciti.
natevw,

@natevw Felice di sapere che non sono solo. :-)
mgd

Risposte:


2

Questa segnalazione di bug afferma che il problema riguarda l' implementazione di netstat . Il codice allegato alla segnalazione di bug mostra correttamente i socket nello stato TIME_WAIT. Devi rimuovere le seguenti righe

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

per farlo mostrare socket associati a localhost.


0

Questa non è una risposta, ma qualcuno potrebbe forse scavare di più da questo.

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

"WTH !? Chi rispedisce questo pacchetto? Il processo del server è chiuso!" Sembra essere inviato dal server che si trova nello stato TIME_WAIT, perché è la parte che invia il primo FIN. Anche se il processo del server è stato terminato, lo stack TCP mantiene lo stato della connessione per inviare l'ultimo ACK.
neverov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.