Сервер получает и обрабатывает первое сообщение клиента.
Преобразование
адреса в идентификатор ассоциации
31-35
Сервер вызывает функцию из листинга 23.13 для получения идентификатора ассоциации по ее адресу. Если что-то мешает серверу получить идентификатор, он не делает попыток породить дочерний процесс, а просто переходит к обработке следующего сообщения.
Выделение ассоциации
36-40
Сервер выделяет ассоциацию в отдельный дескриптор сокета при помощи
sctp_peeloff
. Полученный сокет типа «один-к-одному» может быть без проблем передан написанной ранее для TCP функции
str_echo
.
Передача работы дочернему процессу
41-47
Сервер порождает дочерний процесс, который и выполняет всю обработку по конкретному дескриптору.
23.11. Управление таймерами
Протокол SCTP имеет множество численных пользовательских параметров. Все они устанавливаются через параметры сокетов, рассмотренные в разделе 7.10. Далее мы займемся рассмотрением нескольких параметров, определяющих задержку перед объявлением об отказе ассоциации или адреса собеседника.
Время обнаружения отказа в SCTP определяется семью переменными (табл. 23.1).
Таблица 23.1. Поля таймеров SCTP
Поле
Описание
По умолчанию
Единицы
srto_min
Минимальный тайм-аут повторной передачи
1000
Мс
srto_max
Максимальный тайм-аут повторной передачи
60000
Мс
srto_initial
Начальный тайм-аут повторной передачи
3000
Мс
sinit_max_init_timeo
Максимальный тайм-аут повторной передачи сегмента INIT
3000
Мс
sinit_max_attempts
Максимальное количество повторных передач сегмента INIT
8
попыток
spp_pathmaxrxt
Максимальное количество повторных передач по адресу
5
попыток
sasoc_asocmaxrxt
Максимальное количество повторных передач на ассоциацию
10
попыток
Эти параметры можно воспринимать как регуляторы, укорачивающие и удлиняющие время обнаружения отказа. Рассмотрим два сценария.
1. Конечная точка SCTP пытается открыть ассоциацию с собеседником, отключившимся от сети.
2. Две многоинтерфейсные конечные точки SCTP обмениваются данными. Одна из них отключается от сети питания в момент передачи данных. Сообщения ICMP фильтруются защитными экранами и потому не достигают второй конечной точки.
(3000 мс). После первой повторной передачи пакета INIT таймер устанавливается на значение 6000 мс. Это продолжается до тех пор, пока не будет сделано
sinit_max_attempts
попыток (9 штук), между которыми пройдут семь тайм-аутов. Удвоение таймера закончится на величине
sinit_max_init_timeo
,
равной 60 000 мс. Таким образом, через 3 + 6 + 12 + 24 + 48 + 60 + 60 + 60 = 273 с стек SCTP объявит потенциального собеседника недоступным.
Вращением нескольких «ручек» мы можем удлинять и укорачивать это время. Начнем с двух параметров, позволяющих уменьшить общую задержку. Сократим количество повторных передач, изменив переменную
sinit_max_attempts
. Альтернативное изменение может состоять в уменьшении максимального тайм- аута для пакета INIT (переменная
srto_max_init_timeo
). Если количество попыток снизить до 4, время детектирования резко упадет до 45 с (одна шестая первоначального значения). Однако у этого метода есть недостаток: из-за проблем в сети или перегруженности собеседника мы можем объявить его недоступным, даже если это состояние является лишь временным.
Другой подход состоит в уменьшении
srto_max_init_timeo
до 20 с. При этом задержка до обнаружения недоступности сократится до 121 с — менее половины исходной величины. Однако и это решение является компромиссным. Если мы выберем слишком низкое значение тайм-аута, при большой сетевой задержке мы будем отправлять гораздо больше пакетов INIT, чем это требуется на самом деле.
Перейдем теперь к сценарию 2, описывающему взаимодействие двух многоинтерфейсных узлов. Одна конечная точка имеет адреса IP-A и IP-B, другая IP-X и IP-Y. Если одна из них становится недоступна, а вторая отправляет какие-то данные, последней приходится делать повторные передачи по каждому из адресов с задержкой, начинающейся с
srto_min
(по умолчанию 1 с) и последовательно удваивающейся до значения
srto_max
(по умолчанию 60 с). Повторные передачи будут продолжаться до тех пор, пока не будет достигнуто ограничение на их количество
sasoc_asocmaxrxt
(по умолчанию 10 повторных передач).
В нашем сценарии последовательность тайм-аутов будет иметь вид 1(IP-A) + 1(IP-B) + 2(IP-A) + 2(IP-B) + 4(IP-A) + 4(IP-B) + 8(IP-A) + 8(IP-B) + 16(IP-A) + 16(IP-B), что в общей сложности составит 62 с. Параметр srto_max не влияет на работу многоинтерфейсного узла, если его значение совпадает с установленным по умолчанию, потому что ограничение на количество передач для ассоциации
sasoc_asocmaxrxt
действует раньше, чем
srto_max
. Опять-таки, у нас есть два параметра влияющих на длительность тайм-аутов и эффективность обнаружения отказов. Мы можем уменьшить количество попыток, изменив значение
sasoc_asocmaxrxt
(по умолчанию 10), или снизить максимальное значение тайм-аута, изменив значение
srto_max
(по умолчанию 60 с). Если мы сделаем
srto_max
равным 10 с, время обнаружения отказа собеседника снизится на 12 с и станет равным 50 с. Альтернативой может быть уменьшение количества повторных передач до 8; при этом время обнаружения снизится до 30 с. Изложенные ранее соображения относятся и к этому сценарию: кратковременные неполадки в сети и перегрузка удаленной системы могут привести к обрыву работоспособного соединения.
Одну из множества альтернатив мы не рассматриваем в качестве рекомендуемой. Это снижение минимального тайм-аута (
srto_min
). При передаче данных через Интернет снижение этого значения приведет к неприятным последствиям: наш узел будет передавать повторные пакеты слишком часто, перегружая инфраструктуру Интернета. В частной сети снижение этого значения допустимо, но для большинства приложений в этом просто нет необходимости.
Для каждого приложения выбор конкретных значений параметров повторной передачи должен определяться несколькими факторами:
Насколько быстро нужно приложению обнаруживать отказы?
Будет ли приложение выполняться в частных сетях, где условия передачи заранее известны и меняются не так резко, как в Интернете?