Литмир - Электронная Библиотека

Чтобы справиться с этой ситуацией, может использоваться другая схема. В этой модели используется специальный процесс, называющийся сопоставителем портов (portmapper). Чтобы найти TSAP-адрес, соответствующий данному имени службы, например «BitTorrent», пользователь устанавливает соединение с сопоставителем портов (TSAP-адрес которого всем известен). Затем пользователь посылает сообщение с указанием названия нужной ему услуги, и сопоставитель портов сообщает ему TSAP-адрес этой службы. После этого пользователь разрывает соединение с сопоставителем портов и устанавливает новое соединение с нужной ему службой.

В этой модели, когда создается новая служба, она должна зарегистрироваться на сопоставителе портов, сообщив ему название услуги (обычно строка ASCII) и TSAP-адрес. Сопоставитель портов сохраняет полученную информацию в своей базе данных, чтобы иметь возможность отвечать на будущие запросы.

Функция сопоставителя портов аналогична работе оператора телефонной справочной службы — он преобразует имена в номера. Как и в телефонной системе, важно, чтобы TSAP-адрес сопоставителя портов (или обрабатывающего сервера в протоколе начального соединения) был действительно хорошо известен. Если вы не знаете номера телефонной справочной, вы не сможете позвонить оператору. Если вы полагаете, что номер справочной является очевидным, попытайтесь угадать его, находясь в другой стране.

Компьютерные сети. 5-е издание - _325.jpg

Рис. 6.6. Пользовательский процесс хоста 1 устанавливает соединение с почтовым сервером хоста 2 через обрабатывающий сервер

Так как многие из серверных процессов, существующих на конкретной машине, используются редко, слишком расточительным делом оказывается поддержка всех их в активном состоянии с постоянными TSAP-адресами. Альтернативный вариант показан в упрощенном виде на рис. 6.6. Он называется протоколом начального соединения (initial connection protocol). Вместо того чтобы назначать всем возможным серверам хорошо известные TSAP-адреса, каждая машина, желающая предоставлять услуги удаленным пользователям, обзаводится специальным обрабатывающим сервером (process server), действующим как прокси (посредник) для менее активно используемых серверов. В UNIX-системах такой сервер называется inetd. Он прослушивает одновременно несколько портов, ожидая запроса на соединение. Потенциальные пользователи начинают с того, что посылают запрос CONNECT, указывая TSAP-адрес нужной им службы. Если никакой сервер их не ждет, они получают соединение с обрабатывающим сервером, как показано на рис. 6.6, а.

Получив запрос, обрабатывающий сервер порождает подпроцесс запрошенного сервера, позволяя ему унаследовать существующее соединение с пользователем. Новый сервер выполняет требуемую работу, в то время как обрабатывающий сервер возвращается к ожиданию новых запросов, как показано на рис. 6.6, б. Этот метод работает только в тех случаях, когда серверы могут создаваться по требованию.

6.2.2. Установка соединения

Установка соединения, хотя и просто звучит, неожиданно оказывается весьма непростым делом. На первый взгляд, должно быть достаточно одной транспортной подсистеме послать адресату сегмент с запросом соединения CONNECTION REQUEST и услышать в ответ CONNECTION ACCEPTED (соединение принято). Неприятность заключается в том, что сеть может потерять, задержать, повредить или дублировать пакеты.

Представьте себе сеть настолько перегруженную, что подтверждения практически никогда не доходят вовремя, каждый пакет опаздывает и пересылается повторно по два-три раза. Предположим, что сеть основана на дейтаграммах и что каждый пакет следует по своему маршруту. Некоторые пакеты могут застрять в давке и прийти с большим опозданием в тот момент, когда отправитель будет думать, что они утеряны.

Самый кошмарный сценарий выглядит следующим образом. Пользователь устанавливает соединение с банком и посылает сообщение с требованием банку перевести крупную сумму денег на счет не совсем надежного человека. К несчастью, пакеты решают прогуляться по замысловатому маршруту, посетив самые отдаленные уголки сети. Тем временем отправитель вынужден выполнить повторную передачу пакетов. На этот раз они идут по кратчайшему пути и доставляются быстро, в результате чего отправитель разрывает соединение.

Происходит очередная неудача: первая порция пакетов выходит из укрытия и добирается до адресата в нужном порядке, предлагая банку установить новое соединение и (снова) выполнить перевод денег. У банка нет способа определить, что это дубликаты. Он решает, что это вторая независимая транзакция, и еще раз переводит деньги.

Такой сценарий может показаться маловероятным или даже неправдоподобным, но идея состоит вот в чем: протоколы должны работать корректно во всех случаях. Самые часто встречающиеся ситуации должны быть реализованы с максимальной эффективностью, требующейся для высокой производительности сети, однако протокол должен уметь справляться и с редкими сценариями, не приводя к сбоям. В противном

случае сеть будет ненадежной и может неожиданно сломаться, даже не сообщив об ошибке.

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

Эту проблему можно попытаться решить несколькими способами, ни один из которых, на самом деле, не является удовлетворительным. Так, например, можно использовать одноразовые транспортные адреса. При таком подходе каждый раз, когда требуется транспортный адрес, генерируется новый адрес. Когда соединение разрывается, этот адрес уничтожается. В таком случае задержавшиеся дубликаты пакетов не смогут найти транспортный адрес и, следовательно, перестанут представлять угрозу. Однако при этом установление соединения с процессом окажется более трудной задачей.

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

К сожалению, у этой схемы есть существенный изъян: требуется, чтобы каждая транспортная подсистема хранила неопределенно долго некоторое количество информации об истории соединений, причем эту информацию должен хранить как отправитель, так и получатель. Иначе, если машина выйдет из строя и потеряет свою память, она уже не сможет определить, какие соединения уже использовались, а какие нет.

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

Время жизни пакета может быть ограничено до известного максимума с помощью одного из следующих методов:

1.    Проектирование сети с ограничениями.

2.    Помещение в каждый пакет счетчика транзитных участков.

3.    Помещение в каждый пакет временного штампа.

К первому способу относятся все методы, предотвращающие зацикливание пакетов, в комбинации с ограничением задержки, включая перегрузки по самому длинному возможному пути. Осуществить эту идею достаточно трудно, учитывая, что интерсеть может охватывать как один город, так и весь мир. Второй метод заключается в начальной установке счетчика на определенное значение и уменьшении на единицу этого значения на каждом маршрутизаторе. Сетевой протокол передачи данных просто игнорирует все пакеты, значение счетчика которых дошло до нуля. Третий метод состоит в том, что в каждый пакет помещается время его создания, а маршрутизаторы договариваются игнорировать все пакеты старше определенного времени. Для последнего метода требуется синхронизация часов маршрутизаторов, что само по себе является нетривиальной задачей. На практике возраст пакета можно довольно точно вычислять с помощью счетчика транзитных участков.

180
{"b":"639789","o":1}