Sunday, Feb 05th

Last update12:13:00 PM GMT

Вы находитесь на: FreeBSD Сетевые протоколы MTU. Установление соединения

MTU. Установление соединения

Имеются два способа, какими может быть установлено новое TCP-соединение. Установление соединения инициируется вызовом connect, тогда как пассивное соединение создается, когда слушающий сокет получает запрос соединения. Мы рассмотрим каждый из них по очереди.

Начальные шаги попытки активного установления соединения сходны с действиями, предпринимаемыми при создании сокета UDP. Процесс создает новый сокет, приводя к вызову процедуры tcp_attach(). TCP создает управляющий блок протокола inpcb, а затем создает дополнительный управляющий блок (структуру tcpcb). Некоторые из параметров управления потоком в tcpcb инициализируются в это время. Если процесс явным образом привязывает к соединению адрес или номер порта, действия идентичны действиям для сокета UDP. Затем вызов tcp_connect() инициирует фактическое соединение.

Первым шагом является установка ассоциации с in_pcbconnect(), опять-таки идентично этому шагу в UDP. Для использования в конструировании каждого выходного пакета создается шаблон заголовка пакета. Из прототипа номера последовательности выбирается начальный номер последовательности, который затем увеличивается на значительную величину. Потом сокет помечается с помощью soisconnecting(), состояние TCP устанавливается в TCPSSYNSENT, дежурный таймер устанавливается (в 75 секунд) для ограничения продолжительности попытки соединения, и в первый раз вызывается tcpoutput().

Модуль обработки вывода tcp_output() использует набор управляющих флагов пакета, индексируемых по состоянию соединения, чтобы определить, какие управляющие флаги должны быть установлены в каждом состоянии. В состоянии TCPSSYNSENT отправляется флаг SYN. Поскольку ей нужно отправить управляющий флаг, система отправляет пакет немедленно, используя только что сконструированный прототип и включив текущие параметры управления потоком. Пакет обычно содержит три поля опций: опцию максимального размера сегмента, опцию масштабирования окна и опцию отметки времени. Опция максимального размера сегмента сообщает наибольший размер сегмента, который хочет принимать TCP. Чтобы вычислить это значение, система находит маршрут до места назначения.

Если маршрут указывает максимальный блок передачи (MTU), система использует это значение после разрешения заголовков пакетов. Если соединение до места назначения в локальной сети, используется максимальный блок передачи исходящего сетевого интерфейса, возможно округленный в сторону уменьшения до кратного размеру кластера mbuf для эффективности буферирования. Если место назначения не является локальным, а про промежуточный путь ничего не известно, используется размер сегмента по умолчанию (512 октетов).

В более ранних версиях FreeBSD многие из важных переменных, относящихся к соединениям TCP, такие, как MTU пути между двумя конечными точками, и данные, использующиеся для управления соединением, содержались в корневом элементе, который описывал соединение, и в элементе маршрутизации в виде набора метрик маршрута. Для централизации всей этой информации в одном удобном для нахождения места был разработан кеш хоста TCP таким образом, чтобы информация, которая была собрана для одного соединения, могла быть повторно использована при открытии нового соединения с той же самой конечной точкой. Все переменные, сохраненные в элементе кеша хоста, описаны в различных частях последующих разделов данной главы тогда, когда они имеют отношение к нашему обсуждению того, как TCP управляет соединением.

Каждый раз при открытии нового соединения делается вызов tcp_hc_get() для нахождения всех сведений о прошлых соединениях. Если существует элемент в кеше для целевой конечной точки, TCP использует кешированную информацию для того, чтобы принимать более обоснованные решения об управлении соединением. Когда соединение закрывается, кеш хоста обновляется соответствующей информацией, которая была обнаружена в ходе соединения между двумя хостами. У каждого элемента хоста есть время жизни по умолчанию в один час. Каждый раз, когда осуществляется доступ к или его обновление, восстанавливается время его жизни в один час. Каждые пять минут вызывается процедура tcp_hc_purge(), чтобы очистить все элементы, у которых истек срок. Очистка от старых элементов гарантирует, что кеш хоста не становится слишком большим и что он всегда будет содержать относительно свежие данные.

TCP может использовать определение MTU пути, как описано в Mogul & Deering [1990]. Определение MTU пути является процессом, посредством которого система зондирует сеть, чтобы обнаружить, каким является максимальный блок передачи в определенном маршруте между двумя узлами. Он делает это путем отправки пакетов с установленным в каждом пакете IP флагом не фрагментировать. Если пакет на своем пути до места назначения сталкивается с участком, на котором его пришлось бы фрагментировать, он уничтожается промежуточным маршрутизатором, а отправителю возвращается ошибка. Сообщение об ошибке содержит пакет максимального размера, который примет участок. Эта информация записывается в кеш хоста TCP для соответствующей конечной точки, и предпринимается попытка передачи с меньшим MTU. После установления соединения, когда достаточное количество пакетов прошли через сеть для установления ТСР-соединения, исправленный MTU, записанный в кеш хоста, подтверждается. Пакеты будут продолжать передаваться с установленным флагом не фрагментировать таким образом, что, если путь к узлу изменится и у этого пути будет даже еще меньший MTU, будет записан этот меньший MTU. FreeBSD в настоящее время не имеет способа увеличения размера MTU при изменении маршрута.

Когда соединение открывается впервые, таймер повторной передачи устанавливается в значение по умолчанию (6 секунд), поскольку информация о времени обращения пока еще недоступна. Если повезет, ответный пакет будет получен от места назначения соединения до того, как истечет время таймера повторной передачи. Если нет, пакет передается повторно, и таймер повторной передачи запускается снова с большим значением. Если ответа не получено до истечения дежурного таймера, попытка соединения прерывается с ошибкой «Тайм-аут попытки соединения». Однако, если получен ответ, проверяется его соответствие исходящему запросу. Он должен подтверждать SYN, который был отправлен, и должен включать SYN. Если оба условия выполнены, инициализируются переменные последовательностей, и состояние соединения переходит в TCPSESTABLISHED. Если в ответе присутствует опция максимального размера сегмента, в качестве максимального размера сегмента для соединения устанавливается минимальное из значений предложенного размера и максимального блока передачи для исходящего интерфейса; если эта опция отсутствует, записывается значение по умолчанию (512 байтов). В управляющем блоке TCP устанавливается флаг TFACKNOW, прежде чем вызвать процедуру вывода, чтобы немедленно подтвердить SYN. Теперь соединение готово к передаче данных.

События, которые происходят, когда соединение создается при помощи пассивного открытия, отличаются от описанных. Создается сокет, и к нему как прежде привязывается адрес. Затем сокет помечается вызовом listen как желающий принимать соединения. Когда для сокета TCP в состоянии TCPSLISTEN прибывает пакет, создается новый сокет с помощью sonewconn(), который вызывает процедуру tcp_usr_attach() для создания управляющих блоков протокола для нового сокета. Новый сокет помещается в очередь частичных соединений, возглавляемых слушающим сокетом. Если пакет содержит SYN и является приемлемым в других отношениях, связь нового сокета привязывается, инициализируется как последовательный номер отправки, так и приемный последовательный номер, а состояние соединения переходит в TCPS_SYN_RECEIVED.

Дежурный таймер устанавливается, как раньше, а после установки TFACKNOW для форсирования подтверждения SYN вызывается процедура вывода; также отправляется исходящий SYN. Если этот SYN подтверждается должным образом, новый сокет перемещается из очереди частичных соединений в очередь полностью установленных соединений. Если владелец прослушивающего сокета находится в состоянии сна в вызове accept или выполняет select, сокет будет указывать, что доступно новое соединение. В конечном счете сокет снова готов к отправке данных. Ко времени завершения вызова accept может быть получено и подтверждено вплоть до одного окна данных.


Похожие:
Еще по теме:
Советуем прочитать:

Сейчас 20 гостей онлайн