Персональный | |
FreeBSD 4.3 и Initial Sequence Number
26.04.2002
Год назад вышла FreeBSD 4.3, в которой была проблема, связанная
с изменением алгоритма генерации начального номера последовательности
(ISN, Initial Sequence Number) TCP соединения.
С ней можно столкнуться, если потестировать Apache
входящей в его дистрибутив программой или же просто работает очень долго.Server timed out : Operation now in progress Суть проблемы в следующем. После закрытия соединения каждый сокет на серверной стороне в течение 60 секунд (2*MSL) находится в состоянии TIME_WAIT. В этом состоянии новое соединение с такими же параметрами (то есть, с такими же портами и адресами удалённой и локальной сторон) возможно лишь в том случае, если ISN пришедшего пакета с флагом SYN больше номера последовательности соединения, находящегося в состоянии TIME_WAIT. В противном случае соединение не устанавливается и на удалённой стороне висит в состоянии SYN_SENT. Поскольку на FreeBSD 4.3 для исходящих соединений используется 3976 портов в диапазоне 1024-5000, то после установления 3976 соединений, локальные порты повторяются. Проблемы не возникает, если машина не успевает обработать 3976 запросов за 60 секунд, так как ко времени обработки 3977 запроса первое соединение, находившееся в состоянии TIME_WAIT, уже будет удалено. Однако сейчас такие машины нужно поискать например, Apache на P3-733 обрабатывает 3976 статических запросов всего за 3.6 секунды. В качестве некоторого решения этой проблемы можно увеличить диапазон портов, используемых для исходящих соединений на клиентской стороне, с помощью sysctl net.inet.ip.portrange.first и net.inet.ip.portrange.last они равны 1024 и 5000 соответственно. Интересно, что, согласно Стивенсу (Stevens, UNIX NetworkТакже можно уменьшить время MSL на серверной стороне с помощью sysctl net.inet.tcp.msl, по умолчанию равное 30000 миллисекундам. История появления и исправления проблемы такова. 17.04.2001 во FreeBSD 5.0-CURRENT был изменён способ генерации ISN вместо предыдущего метода, в котором номера генерировались случайно, но при этом всегда увеличивались, был взят алгоритм из OpenBSD, в котором номера генерируются просто случайным образом. Понятно, что при этом вероятность установления 3977-го соединения равна 50%. 18.04.2001 изменения были внесены и в FreeBSD-4.3-RELEASE, а 2.05.2001 и в FreeBSD-3.5-STABLE. Однако, пересобрав ядро с опцией можно было восстановить старый вариант генерации. Но 22.06.2001 из FreeBSD 4.3-STABLE эта опция была удалена. Во FreeBSD 5.0-CURRENT это случилось сразу же после импортирования нового варианта 20.04.2001. 8.07.2001 в обеих системах появился sysctl net.inet.tcp.tcp_seq_genscheme, позволяющий на ходу менять вариант генерации. По умолчанию он был равен единице, означающей алгоритм OpenBSD. Ноль означал старый алгоритм. 22.08.2001 две схемы генерации в обеих системах были заменены на схему, описанную в RFC 1948, и этот sysctl был удалён. Однако упоминание о нём забыли удалить из Release Notes FreeBSD 4.4-RELEASE.option TCP_COMPAT_42 (C) Игорь Сысоев |