По умолчанию, когда оба tcp_tw_reuse
и tcp_tw_recycle
отключены, ядро будет гарантировать, что сокеты в TIME_WAIT
состоянии будут оставаться в этом состоянии достаточно долго - достаточно долго, чтобы быть уверенным, что пакеты, принадлежащие будущим соединениям, не будут приняты за поздние пакеты старого соединения.
Когда вы включаете tcp_tw_reuse
, сокеты в TIME_WAIT
состоянии могут использоваться до истечения срока их действия, и ядро будет пытаться убедиться, что нет никаких конфликтов в отношении порядковых номеров TCP. Если вы включите tcp_timestamps
(иначе говоря, PAWS, для защиты от последовательных номеров), это будет гарантировать, что эти столкновения не произойдут. Однако вам нужно, чтобы временные метки TCP были активированы на обоих концах (по крайней мере, я так понимаю). Смотрите определение tcp_twsk_unique для подробностей.
Когда вы включаете tcp_tw_recycle
, ядро становится намного более агрессивным и делает предположения о временных метках, используемых удаленными хостами. Он будет отслеживать последнюю временную метку, используемую каждым удаленным хостом, имеющим соединение в TIME_WAIT
состоянии), и позволит повторно использовать сокет, если временная метка была правильно увеличена. Однако, если временная метка, используемая хостом, изменится (т. Е. Деформируется во времени), SYN
пакет будет автоматически отброшен, и соединение не будет установлено (вы увидите ошибку, похожую на «время ожидания соединения»). Если вы хотите погрузиться в код ядра, определение tcp_timewait_state_process может быть хорошей отправной точкой.
Теперь метки времени никогда не должны возвращаться во времени; если:
- хост перезагружается (но к тому времени, когда он возвращается,
TIME_WAIT
сокет, вероятно, истек, так что это не проблема);
- IP-адрес быстро повторно используется чем-то другим (
TIME_WAIT
соединения останутся немного, но другие соединения, вероятно, будут сбиты, TCP RST
и это освободит некоторое пространство);
- Трансляция сетевых адресов (или брандмауэр Smarty-Tants) участвует в середине соединения.
В последнем случае вы можете иметь несколько хостов за одним и тем же IP-адресом, и, следовательно, разные последовательности временных меток (или указанные временные метки рандомизируются при каждом соединении межсетевым экраном). В этом случае некоторые хосты не смогут случайным образом подключиться, поскольку они сопоставлены с портом, для которого TIME_WAIT
сегмент сервера имеет более новую временную метку. Вот почему в документах говорится, что «устройства NAT или балансировщики нагрузки могут начать отбрасывать кадры из-за настроек».
Некоторые люди рекомендуют оставить в tcp_tw_recycle
покое, но включить tcp_tw_reuse
и опуститьtcp_timewait_len
. Я согласен :-)