Domyślnie, gdy oba tcp_tw_reuse
i tcp_tw_recycle
są wyłączone, jądro będzie upewnić się, że gniazda w TIME_WAIT
stanie pozostanie w tym stanie wystarczająco długo - wystarczająco długo, aby mieć pewność, że pakiety należące do połączeń przyszłości nie będą mylone z późnych pakietów starego połączenia.
Gdy włączysz tcp_tw_reuse
, gniazda w TIME_WAIT
stanie mogą być używane przed ich wygaśnięciem, a jądro spróbuje upewnić się, że nie dojdzie do kolizji w odniesieniu do numerów sekwencji TCP. Jeśli włączysz tcp_timestamps
(inaczej PAWS, dla ochrony przed zawiniętymi numerami sekwencji), upewni się, że kolizje te nie będą miały miejsca. Musisz jednak włączyć znaczniki czasu TCP na obu końcach (przynajmniej tak rozumiem). Zobacz definicję tcp_twsk_unique dla szczegółów krwawych.
Po włączeniu tcp_tw_recycle
jądro staje się znacznie bardziej agresywne i przyjmuje założenia dotyczące znaczników czasu używanych przez zdalne hosty. Będzie śledził ostatni znacznik czasu używany przez każdy zdalny host mający połączenie w TIME_WAIT
stanie) i pozwoli na ponowne użycie gniazda, jeśli znacznik czasu prawidłowo się zwiększył. Jeśli jednak znacznik czasu używany przez host zmieni się (tzn. Wypaczy się w czasie), SYN
pakiet zostanie po cichu odrzucony, a połączenie nie zostanie nawiązane (zobaczysz błąd podobny do „limitu czasu połączenia”). Jeśli chcesz zanurzyć się w kodzie jądra, definicja tcp_timewait_state_process może być dobrym punktem wyjścia.
Teraz znaczniki czasu nigdy nie powinny cofać się w czasie; chyba że:
- host zostanie zrestartowany (ale wtedy, zanim wróci,
TIME_WAIT
gniazdo prawdopodobnie wygasło, więc nie będzie problemu);
- adres IP jest szybko ponownie wykorzystywany przez coś innego (
TIME_WAIT
połączenia pozostaną trochę, ale prawdopodobnie inne połączenia zostaną naruszone TCP RST
, co zwolni miejsce);
- translacja adresów sieciowych (lub firewall smarty-pants) jest zaangażowana w połączenie.
W tym drugim przypadku możesz mieć wiele hostów za tym samym adresem IP, a zatem różne sekwencje znaczników czasu (lub wspomniane znaczniki czasu są losowo przydzielane przy każdym połączeniu przez zaporę). W takim przypadku niektóre hosty nie będą mogły połączyć się losowo, ponieważ są mapowane na port, dla którego TIME_WAIT
segment serwera ma nowszą sygnaturę czasową. Dlatego dokumenty mówią, że „urządzenia NAT lub moduły równoważenia obciążenia mogą zacząć upuszczać ramki z powodu ustawienia”.
Niektóre osoby zalecają pozostawienie w tcp_tw_recycle
spokoju, ale włączanie tcp_tw_reuse
i obniżanietcp_timewait_len
. Zgadzam się :-)