Где мои TIME_WAIT в Mac OS X?


9

Нет TIME_WAITна Mac OS X

Обычно, когда соединение TCP закрыто, сокет на стороне, где close()вызывается первым, остается в TIME_WAITсостоянии.

Когда одним из пиров является компьютер Mac OS X (Lion), на Mac не TIME_WAITуказывается no, netstat -anесли close()сначала вызывается на стороне Mac. Однако, похоже, что сокет фактически находится в TIME_WAITсостоянии, потому что попытка вызова listen()снова (без использования параметра сокета SO_REUSEADDR) приводит listen()к сбою.

Ожидание 2 * MSL (максимальное время жизни сегмента, равное 15 секундам в Mac OS X Lion, как сообщается sysctl net.inet.tcp.msl) очищает TIME_WAITсостояние и listen()может быть вызвано снова без ошибок.

Почему я не вижу розетку внутри TIME_WAIT?

тестирование

Вот две простые тестовые программы на Python.

сервер

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

клиент

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

Когда сервер и клиент работают на двух разных машинах Linux, одноранговый узел, который сначала нажимает <enter>для вызова, close()получает TIME_WAITожидаемый результат:

$ ./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  
$ 

Когда одним из пиров является Mac (под управлением OS X Lion), я никогда не вижу его TIME_WAITпри запуске netstat -an | grep 50007после первого закрытия на Mac.


Хороший вопрос. Сам вижу то же самое и не вижу возможности netstat включить их…
natevw

2
FWIW, sudo lsof -i -Pне показывает состояние TIME_WAIT для процессов, которые уже вышли.
natevw

@natevw Рад узнать, что я не одинок. :-)
mgd

Ответы:


2

В этом отчете об ошибке утверждается, что проблема в реализации netstat . Код, прикрепленный к отчету об ошибке, правильно отображает сокеты в состоянии TIME_WAIT. Вам необходимо удалить следующие строки

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

чтобы он показывал сокеты, привязанные к localhost.


0

Это не ответ, но кто-то может извлечь из этого больше информации.

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 !? Кто отправит обратно этот пакет? Процесс сервера закрыт!" Кажется, он отправляется сервером, который находится в состоянии TIME_WAIT, потому что это часть, отправляющая первый FIN. Несмотря на то, что процесс сервера был прерван, стек TCP поддерживает состояние соединения для отправки последнего ACK.
Неверов
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.