- •7.5.2. Трехфазное подтверждение
- •7.6. Восстановление
- •7.6.1. Основные понятия
- •7.6.2. Создание контрольных точек
- •7.6.3. Протоколирование сообщений
- •7.7. Итоги
- •Глава 8
- •8.1. Общие вопросы защиты
- •8.1.1. Угрозы, правила и механизмы
- •8.1.2. Вопросы разработки
- •8.1.3. Криптография
- •8.2. Защищенные каналы
- •8.2.1. Аутентификация
- •8.2.2. Целостность и конфиденциальность сообщений
- •8.2.3. Защищенное групповое взаимодействие
- •8.3. Контроль доступа
- •8.3.1. Общие вопросы контроля доступа
- •8.3.2. Брандмауэры
- •8.3.3. Защита мобильного кода
- •8.4. Управление защитой
- •8.4.1. Управление ключами
- •8.4.2. Управление защищенными группами
- •8.4.3. Управление авторизацией
- •8.5. Пример — Kerberos
- •8.6. Пример — sesame
- •8.6.1. Компоненты системы sesame
- •8.6.2. Сертификаты атрибутов привилегий
- •8.7. Пример — электронные платежные системы
- •8.7.1. Электронные платежные системы
- •8.7.2. Защита в электронных платежных системах
- •8.7.3. Примеры протоколов
- •8.8. Итоги
- •Глава 9
- •9.1. Corba
- •9.1.1. Обзор
- •9.1.2. Связь
- •9.1.3. Процессы
- •9.1.4. Именование
- •9.1.5. Синхронизация
- •9.1.6. Кэширование и репликация
- •9.1.7. Отказоустойчивость
- •9.1.8. Защита
- •9.2. Dcom
- •9.2.1. Обзор
- •9.2.2. Связь
- •9.2.3. Процессы
- •9.2.4. Именование
- •Синхронизация
- •Репликация
- •Отказоустойчивость
- •9.2.8. Защита
- •9.3. Globe
- •9.3.1. Обзор
- •9.3.2. Связь
- •9.3.3. Процессы
- •9.3.4. Именование
- •9.3.5. Синхронизация
- •9.3.6. Репликация
- •Отказоустойчивость
- •9.4. Сравнение систем corba, dcom и Globe
- •9.4.1. Философия
- •Процессы
- •9.4.4. Именование
- •Синхронизация
- •Кэширование и репликация
- •Отказоустойчивость
9.1.2. Связь
Исходно CORBA имеет простую модель связи: клиент обращается к методу объекта и ожидает ответа. Эта модель разрабатывалась так, чтобы быть как можно проще, но при необходимости существовала возможность добавлять к ней дополнительные методы взаимодействия. В связи с этим мы особо рассмотрим обращение к средствам в CORBA, обсудив также альтернативы подобного обращения к объектам. Как мы увидим, расширения базовой модели обращения к объекту вызываются необходимостью поддержания асинхронного взаимодействия. Эта необходимость вызывается также фактом существования других моделей передачи сообщений, которые мы обсуждали в главе 2.
Модели обращения к объектам
По умолчанию, когда клиент обращается к объекту, он посылает запрос соответствующему серверу объектов и блокируется до получения ответа. При отсутствии ошибок эта семантика полностью соответствует обычному обращению к методам, когда вызывающая и вызываемая стороны находятся в одном адресном пространстве.
Однако при наличии ошибок все усложняется. В случае описанного выше синхронного обращения клиент в результате получает исключение, указывающее на незаконченность обращения. CORBA определяет, что в этом случае обращение следует семантике «максимум однажды», которая предполагает, что вызываемый метод будет выполнен один раз или не будет выполнен вообще. Отметим, что реализация должна поддерживать эту семантику.
Следовательно, синхронные обращения полезны, когда клиенту нужно дождаться ответа. Если возвращается правильный результат, CORBA гарантирует, что метод был выполнен ровно один раз. Однако в том случае, когда ответ не требуется, для клиента лучше просто вызвать метод и как можно быстрее продолжить выполнение. Этот тип обращения соответствует асинхронному вызову RPC, который мы обсуждали в главе 2.
В CORBA такой тип асинхронных обращений именуется односторонним запросом (one-way request). Метод может быть определен как односторонний только в том случае, если он не возвращает результата. Однако в отличие от гарантированной доставки асинхронных вызовов RPC, односторонние запросы CORBA предполагают наличие только службы доставки «с максимальными усилиями» (best effort delivery). Другими словами, отправитель не получает никаких гарантий того, что запрос будет доставлен серверу объектов.
Кроме односторонних запросов CORBA поддерживает также механизм так называемого отложенного синхронного запроса (deferred synchronous request). Такой запрос, который фактически является вариантом одностороннего запроса, позволяет серверу возвращать результат клиенту асинхронно. После того как клиент посылает серверу свой запрос, он может, не дожидаясь ответа, сразу же продолжать работу. Другими словами, клиент не знает, был его запрос в действительности доставлен серверу или нет.
Эти три различных модели обращения обобщены в табл. 9.2.
Службы событий и уведомлений
Хотя модели обращений, предлагаемые CORBA, вполне покрывают задачи связи в распределенной системе объектов, чувствуется, что одних обращений к объектам недостаточно. В частности, необходимо наличие службы, которая должна просто сигнализировать о наступлении событий. Клиенты, узнав об этом событии, смогут выполнить соответствующие действия.
Результатом является определение службы событий (event service). Базовая модель событий в CORBA очень проста. Каждое событие ассоциируется с единичным элементом данных, обычно представленным в виде ссылки на объект или же значением, характерным для данного приложения. Событие генерирует поставщик (supplier) и получает потребитель (consumer). События доставляются по каналу событий (event channel), логически связывающего поставщика и потребителя, как показано на рис. 9.3.
На рисунке показана так называемая модель продвижения (push model). Согласно этой модели при возникновении определенной ситуации поставщик генерирует событие и продвигает его через канал событий, по которому событие доставляется потребителям. Модель продвижения напоминает асинхронный режим работы, который часто ассоциируют с событиями. На практике потребители пассивно ожидают прихода события, полагая, что при возникновении события их работа будут так или иначе прервана.
Альтернативная модель, также поддерживаемая CORBA, — это модель извлечения (pull model), продемонстрированная на рис. 9.4. Согласно этой модели потребители опрашивают канал событий, проверяя, не произошло ли ожидаемое событие. Канал событий, в свою очередь, опрашивает поставщиков событий.
Хотя служба событий имеет простой и надежный способ распространения событий, у него есть несколько серьезных недостатков. Для распространения событий необходимо, чтобы поставщики и потребители были соединены с каналом событий. Это также означает, что если потребитель соединится с каналом после того, как событие произошло, это событие будет потеряно. Другими словами, служба сообщений CORBA не обеспечивает сохранности событий.
Очень важно, что потребители не в состоянии предпринять каких-либо мер для фильтрации событий. Любое событие, в принципе, пересылается всем потребителям. Если необходимо выделять различные типы событий, нужно создавать отдельные каналы событий для каждого из этих типов. Средства фильтрации имеются в расширении [325], известном под названием службы уведомлений (notification service). Помимо всего прочего эта служба содержит средства для предотвращения распространения событий, в которых не заинтересован ни один из потребителей.
И, наконец, распространение событий изначально ненадежно. Спецификация CORBA указывает, что по вопросу доставки событий никаких гарантий не дается. Как мы говорили в главе 2, существуют приложения, для которых надежная доставка событий очень важна. Для таких приложений служба событий CORBA не подходит и требуются другие способы взаимодействия.
Передача сообщений
Любое взаимодействие в CORBA, которое мы обсуждали до сих пор, — нерезидентное. Это означает, что сообщения сохраняются в базовых системах связи лишь в процессе выполнения как отправителя, так и получателя. Как мы говорили в главе 2, существует множество приложений, которые требуют сохранной связи, то есть такой, при которой сообщение хранится в системе до тех пор, пока не будет доставлено. При сохранной связи не имеет значения, выполняется или нет после отправки сообщения отправитель или получатель, в любом случае сообщение будет храниться столько, сколько необходимо.
Хорошо известна такая модель сохранной связи, как очереди сообщений. CORBA поддерживает эту модель в виде дополнительной службы сообщений (messaging service). Обмен сообщениями в CORBA отличается от других систем объектным подходом к взаимодействию. В частности, проектировщики службы сообщений вынуждены были соблюсти условие обязательности обращений к объектам при любом взаимодействии. В случае обмена сообщениями эти ограничения привели к появлению двух дополнительных видов асинхронного обращения к методам.
В модели обратного вызова (callback model) клиент представляет собой объект, реализующий интерфейс, в котором содержатся методы обратного вызова. Базовая коммуникационная система может вызвать эти методы для передачи результата асинхронного обращения. Важная особенность этой модели состоит в том, что асинхронные обращения к методу не влияют на исходную реализацию объекта. Другими словами, преобразовать исходное синхронное обращение в асинхронное — задача клиента; сервер делает обычный (синхронный) вызов.
Построение асинхронного обращения выполняется в два этапа. Сначала исходный интерфейс, реализуемый объектом, заменяется двумя другими, реализуемыми исключительно программным обеспечением клиента. Один из интерфейсов содержит спецификацию методов, которые может вызывать клиент. Ни один из этих методов не возвращает значений и не имеет выходных параметров. Второй интерфейс — это интерфейс обратного вызова. Он содержит методы, которые могут быть вызваны брокером ORB клиента для передачи результатов соответствующего метода вызвавшему его клиенту для всех операций исходного интерфейса.
В качестве примера рассмотрим объект, реализующий простой интерфейс с единственным методом:
int addCin int i. in int j. out int k):
Предположим, что этот метод (который мы описали на IDL для CORBA) получает два неотрицательных целых числа i и j и возвращает i+j в выходном параметре к. Операция должна возвращать -1 в случае неудачного завершения. Преобразование исходного (синхронного) обращения к методу в асинхронное путем обратного вызова происходит так: сначала создается пара описаний методов (для нашей задачи мы предпочли удобство имен строгим правилам именования [331]):
void sendcb_add(in int i. in int j); // Вызывается клиентом
void replycb_add(in int retj/al. in int k); // Вызывается клиентским ORB
В действительности все выходные параметры спецификации исходного метода изымаются из вызываемого клиентом метода и превращаются во входные параметры операции обратного вызова. Точно так же если в исходном методе определялось возвращаемое значение, это значение передается в операцию обратного вызова в качестве входного параметра.
Второй шаг заключается в простой компиляции созданного интерфейса. В качестве результата клиент получает заглушку, которая способна асинхронно вызывать метод sendcbjdd. Однако клиент должен сам предоставить реализацию интерфейса обратного вызова, содержащего, в нашем примере, метод replycb_add. Отметим, что эти изменения не влияют на реализацию объекта на сервере. Описанную модель обратного вызова иллюстрирует рис. 9.5.
В качестве альтернативы обратному вызову CORBA поддерживает модель опроса (polling model). Согласно этой модели клиенту предоставляется набор операций для опроса своего брокера ORB на предмет наличия поступивших результатов. Как и в модели обратного вызова, за преобразование синхронного обращения к методу в асинхронное отвечает клиент. И снова большую часть работы можно выполнять автоматически, отталкиваясь от спецификации соответствующего метода в исходном интерфейсе, который реализован в объекте.
Рассмотрим вновь наш пример. Метод add превратится в следующие два описания методов (и снова для удобства мы используем свои правила именования):
void sendpoll_add(in int i. in int j): // Вызывается клиентом
void replypoll_add(out int ret_val. out int k); // Тоже вызывается клиентом
Наиболее важное различие между моделью опроса и моделью обратного вызова состоит в том, что метод replypoll_add реализуется клиентским брокером ORB. Эта реализация может быть автоматически сгенерирована компилятором IDL. Модель опроса приведена на рис. 9.6. И вновь мы считаем нужным отметить, что исходная реализация объекта на стороне сервера не претерпевает никаких изменений.
В описанных здесь моделях мы не учли тот факт, что сообщения, пересылаемые между клиентом и сервером, в том числе и ответы на асинхронные обращения, в случае неработоспособности клиента или сервера сохраняются базовой системой. К счастью, большинство моментов, связанных с сохранностью связи, не оказывают влияния на эти модели асинхронных обращений. Все, что нам необходимо сделать для создания коллекции серверов сообщений, — это разрешить временное хранение сообщений (будь то обращения или ответы) до момента доставки. Этот подход, описанный в [331], аналогичен системе очередей сообщений IBM, которую мы уже рассматривали в пункте 2.4.4 и не будем повторяться.
Совместимость
Ранние версии CORBA отдавали решение многих вопросов на откуп производителям. В результате системы CORBA разных производителей имеют собственные способы реализации взаимодействия между клиентами и серверами объектов. В частности, клиент может обратиться к объекту на сервере только в том случае, если клиент и сервер используют один и тот же брокер ORB.
Эта проблема совместимости была решена путем введения стандартизованного протокола обмена между различными брокерами ORB в комбинации с универсальным способом создания ссылок на объекты. Если вернуться к рис. 9.2, это означает, что указанная между клиентом и сервером связь обслуживается по стандартному протоколу, который в CORBA известен как обобщенный протокол обмена между ORB (General Inter-ORB Protocol, GIOP).
GIOP — это на самом деле заготовка (каркас) протокола. Предполагается, что конкретная реализация будет выполняться поверх существующего транспортного протокола. Этот транспортный протокол должен быть надежным, ориентированным на соединение, а также поддерживать понятия потока байтов и некоторые другие. Нас не особенно удивляет, что TCP удовлетворяет всем этим требованиям, однако имеются и другие подходящие транспортные протоколы. Реализация GIOP поверх TCP называется Интернет-протоколом обмена между ORB (Internet Inter-ORB Protocol, ПОР).
Протокол GIOP (включая ПОР и другие реализации GIOP) поддерживает восемь типов сообщений, которые перечислены в табл. 9.3. Два наиболее важных типа сообщений — это Request и Reply, которые вместе образуют часть реализации обращений к удаленным методам.
Сообщение Request содержит запрос, полученный после завершения маршалинга обращения, включая ссылку на объект, имя вызываемого метода и все необходимые входные параметры. Ссылка на объект и название метода входят в заголовок. Каждое сообщение Request также содержит собственный идентификатор запроса, с помощью которого впоследствии можно найти соответствующий ответ.
Сообщение Reply содержит возвращаемые значения и выходные параметры (также подвергнутые маршалингу), ассоциируемые с ранее вызванным методом. Нет необходимости полностью указывать объект или метод, достаточно возвратить такой же идентификатор запроса, который был в соответствующем сообщении Request.
Как мы увидим чуть ниже, клиент может потребовать от хранилища реализаций предоставить детальную информацию о том, где размещается некий объект. Такому запросу соответствует посылка сообщения LocateRequest. Хранилище реализаций отвечает на этот запрос посылкой сообщения LocateReply, которое обычно идентифицирует текущий сервер объекта, к которому можно обратиться.
Сообщение Cancel Request может быть послано клиентом серверу в том случае, если клиент хочет отменить действие ранее посланных сообщений Request или
LocateRequest. Отмена запроса означает, что клиент не намерен более ждать ответа сервера. Клиент может отменить посланный запрос по различным причинам, но обычно это связано с окончанием тайм-аута клиентского приложения. Важно отметить, что отмена запроса не означает, что соответствующее обращение вообще не будет выполнено. Справляться с ситуацией должно приложение клиента.
В GIOP клиент всегда устанавливает соединение с сервером сам. Серверы могут лишь принимать или отвергать запросы на установку соединения, но сами устанавливать соединения с клиентами не в силах. Однако и клиент, и сервер имеют право разорвать соединение, для этого они должны послать другой стороне сообщение CloseConnection.
Если при выполнении произошла ошибка, другая сторона уведомляется об этом сообщением MessageError. Это сообщение содержит заголовок сообщения GIOP, вызвавшего ошибку. Такой же подход принят в сообщениях ICMP протокола IP, которые используются для возвращения информации об ошибке, если что-то идет не так. В этом случае заголовок IP-пакета, вызвавшего ошибку, возвращается в форме данных сообщения ICMP.
И, наконец, GIOP позволяет разбивать различные сообщения с запросами и ответами на части. Эта возможность позволяет упростить пересылку между клиентом и сервером больших объемов данных. Отдельные фрагменты пересылаются в виде специальных сообщений Fragment, определяющих исходное сообщение и позволяющих производить сборку этого сообщения на стороне получателя.
