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

B этой главе будет рассмотрен весь сетевой стек Windows — снизу доверху. Сначала мы поговорим о том, как сетевые компоненты Windows соотносятся с уровнями эталонной модели OSI (Open Systems Interconnection). Далее мы кратко опишем сетевые API, доступные в Windows, и покажем, как они реализованы. Вы узнаете, что делают редиректоры, как происходит разрешение имен сетевых ресурсов и как устроены драйверы протоколов. Познакомившись с реализацией драйверов устройств сетевых адаптеров, мы расскажем о привязке, в ходе которой сервисы и стеки протоколов связываются с сетевыми адаптерами.

Сетевая архитектура Windows

Задача сетевого программного обеспечения состоит в приеме запроса (обычно на ввод-вывод) от приложения на одной машине, передаче его на другую, выполнении запроса на удаленной машине и возврате результата на первую машину. B ходе этих операций запрос неоднократно трансформируется. Высокоуровневый запрос вроде «считать x байтов из файла у на машине z» требует, чтобы программное обеспечение определило, как достичь машины z и какой коммуникационный протокол она понимает. Затем запрос должен быть преобразован для передачи по сети — например, разбит на короткие пакеты данных. Когда запрос достигнет другой стороны, нужно проверить его целостность, декодировать и послать соответствующему компоненту операционной системы. По окончании обработки запрос должен быть закодирован для обратной передачи по сети.

Эталонная модель OSI

Чтобы помочь поставщикам в стандартизации и интеграции их сетевого программного обеспечения, международная организация по стандартизации (ISO) определила программную модель пересылки сообщений между компьютерами. Эта модель получила название эталонной модели OSI (Open Systems Interconnection). B ней определено семь уровней программного обеспечения (рис. 13-1).

Эталонная модель OSI — идеал, точно реализованный лишь в очень немногих системах, но часто используемый при объяснении основных принципов работы сети. Каждый уровень на одной из машин считает, что он взаимодействует с тем же уровнем на другой машине. Ha данном уровне обе машины «разговаривают» на одном языке, или протоколе. Ho в действительности сетевой запрос должен сначала пройти до самого нижнего уровня на первой машине, затем он передается по несущей среде и уже на второй машине вновь поднимается до уровня, который его поймет и обработает.

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

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

• Презентационный уровень (presentation layer) Отвечает за форматирование данных, в том числе решает, должны ли строки заканчиваться парой символов «возврат каретки/перевод строки» (CR/LF) или только символом «возврат каретки» (CR), надо ли сжимать данные, кодировать и т. д.

• Сеансовый уровень (session layer) Управляет соединением взаимодействующих приложений, включая высокоуровневую синхронизацию и контроль за тем, какое из них «говорит», а какое «слушает».

• Транспортный уровень (transport layer) Ha передающей стороне разбивает сообщения на пакеты и присваивает им порядковые номера, гарантирующие прием пакетов в должном порядке. Кроме того, изолирует сеансовый уровень от влияния изменений в составе оборудования.

• Сетевой уровень (network layer) Создает заголовки пакетов, отвечает за маршрутизацию, контроль трафика и взаимодействие с межсетевой средой. Это самый высокий из уровней, который понимает топологию сетей, т. е. физическую конфигурацию машин в них, ограничения пропускной способности этих сетей и т. д.

• Канальный уровень (data-link layer) Пересылает низкоуровневые кадры данных, ждет подтверждений об их приеме и повторяет передачу кадров, потерянных в ненадежных линиях связи.

• Физический уровень (physical layer) Передает биты по сетевому кабелю или другой физической несущей среде.

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

Сетевые компоненты Windows

Ha рис. 13-2 представлена общая схема сетевых компонентов Windows, их соответствие уровням модели OSI, а также протоколы, используемые различными уровнями. Как видите, между уровнями OSI и реальными сетевыми компонентами нет точного соответствия. Некоторые компоненты охватывают несколько уровней. Ниже приводится список сетевых компонентов с кратким описанием.

• Сетевые API Обеспечивают независимое от протоколов взаимодействие приложений через сеть. Сетевые API реализуются либо в режиме ядра и пользовательском режиме, либо только в пользовательском режиме. Некоторые сетевые API являются оболочками других API и реализуют специфическую модель программирования или предоставляют дополнительные сервисы. (Термином «сетевые API» обозначаются любые программные интерфейсы, предоставляемые сетевым программным обеспечением.)

• Клиенты TDI (Transport Driver Interface) Драйверы устройств режима ядра, обычно реализующие ту часть сетевого API, которая работает в режиме ядра. Клиенты TDI называются так из-за того, что пакеты запросов ввода-вывода (IRP), которые они посылают драйверам протоколов, форматируются по стандарту Transport Driver Interface (документированному в DDK). Этот стандарт определяет общий интерфейс программирования драйверов устройств режима ядра. (Об IRP см. главу 9)

• Транспорты TDI Представляют собой драйверы протоколов режима ядра и часто называются транспортами, NDlS-драйверами протоколов или драйверами протоколов. Они принимают IRP от клиентов TDI и обрабатывают запросы, представленные этими IRP Обработка запросов может потребовать взаимодействия через сеть с другим равноправным компьютером; в таком случае транспорт TDI добавляет к данным IRP заголовки, специфичные для конкретного протокола (TCP, UDP, IPX), и взаимодействует с драйверами адаптеров через функции NDIS (также документированные в DDK). B общем, транспорты TDI связывают приложения через сеть, выполняя такие операции, как сегментация сообщений, их восстановление, упорядочение, подтверждение и повторная передача.

• Библиотека NDIS (Ndis.sys) Инкапсулирует функциональность для драйверов адаптеров, скрывая от них специфику среды Windows, работающей в режиме ядра. Библиотека NDIS экспортирует функции для транспортов TDI, а также функции поддержки для драйверов адаптеров.

Рис. 13-2. Модель OSI и сетевые компоненты Windows

• Минипорт-драйверы NDIS Драйверы режима ядра, отвечающие за организацию интерфейсов между транспортами TDI и конкретными сетевыми адаптерами. Минипорт-драйверы NDIS пишутся так, чтобы они были заключены в оболочку библиотеки NDIS. Такая инкапсуляция обеспечивает межплатформенную совместимость с потребительскими версиями Microsoft Windows. Минипорт-драйверы NDIS не обрабатывают IRP, а регистрируют интерфейс таблицы вызовов библиотеки NDIS, которая содержит указатели на функции, соответствующие функциям, экспортируемым библиотекой NDIS для транспортов TDI. Минипорт-драйверы NDIS взаимодействуют с сетевыми адаптерами, используя функции библиотеки NDIS, которые вызывают соответствующие функции HAL. Фактически четыре нижних сетевых уровня часто обозначают собирательным термином «транспорт», а компоненты, расположенные на трех верхних уровнях, — термином «пользователи транспорта».

Далее мы подробно рассмотрим сетевые компоненты, показанные на рис. 13-2 (равно как и не показанные на нем), обсудим их взаимосвязи и то место, которое они занимают в Windows.

Сетевые API

Для поддержки унаследованных приложений и для совместимости с промышленными стандартами в Windows реализован целый набор сетевых API. B этом разделе мы расскажем о сетевых API и поясним, как они используются приложениями. Важно иметь в виду, что выбор API для приложения определяется характеристиками APL поверх каких протоколов он может работать, поддерживает ли он надежную и двустороннюю связь, а также переносим ли он на другие Windows-платформы, на которых может работать данное приложение. Мы обсудим следующие сетевые APL

• Windows Sockets (Winsock);

• Remote Procedure Call (RPC);

• API доступа к Web;

• именованные каналы (named pipes) и почтовые ящики (mailslots);

• NetBIOS:

• прочие сетевые API.

Windows Sockets

Изначально Windows Sockets (Winsock) версии 1.0 был Microsoft-реализацией BSD (Berkeley Software Distribution) Sockets, программного интерфейса, с 80-х годов прошлого века ставшего стандартом, на основе которого UNIX-системы взаимодействовали через Интернет. Поддержка сокетов в Windows существенно упрощает перенос сетевых приложений из UNIX в Windows. Современные версии Winsock включают большую часть функциональности BSD Sockets, а также содержат специфические расширения от Microsoft, развитие которых продолжается. Winsock поддерживает как надежные коммуникации, ориентированные на логические соединения, так и ненадежные коммуникации, не требующие логических соединений. Windows предоставляет Winsock 2.2 — для устаревших версий Windows он доступен в виде надстройки. Функциональность Winsock 2.2 выходит далеко за рамки спецификации BSD Sockets, и, в частности, он поддерживает функции, использующие средства асинхронного ввода-вывода в Windows, что обеспечивает гораздо более высокую производительность и масштабируемость, чем исходный BSD Sockets.

Winsock обеспечивает:

• ввод-вывод по механизму «scatter/gather» и асинхронный ввод-вывод;

• поддержку Quality of Service (QoS) — если нижележащая сеть поддерживает QoS, приложения могут согласовывать между собой максимальные задержки и полосы пропускания;

• расширяемость — Winsock можно использовать не только с протоколами, которые он поддерживает в Windows, но и с другими;

• поддержку интегрированных пространств имен, отличных от определенных протоколом, который используется приложением вместе с Winsock. Например, сервер может опубликовать свое имя в Active Directory, а клиент, используя расширения пространств имен, — найти адрес сервера в Active Directory;

• поддержку многоадресных сообщений, передаваемых из одного источника сразу нескольким адресатам.

Далее мы рассмотрим принципы работы Winsock и опишем способы его расширения.

Функционирование Winsock на клиентской стороне

Первый шаг Winsock-приложения — инициализация Winsock API вызовом инициализирующей функции. B Windows 2000 такое приложение должно затем создать сокет, представляющий конечную точку коммуникационного соединения. Приложение получает адрес сервера, к которому ему нужно подключиться, вызовом gethostbyname. Winsock не зависит от конкретного протокола, поэтому адрес может быть указан по любому установленному в системе протоколу, поверх которого работает Winsock (TCP/IP, TCP/IP с IP версии 6, IPX). Получив адрес сервера, клиент, ориентированный на логические соединения (connection-oriented client), пытается подключиться к этому серверу, вызывая функцию connect и передавая ей адрес сервера.

B Windows XP и Windows Server 2003 приложение должно получить адрес сервера через getaddrinfo, а не gethostbyname. Функция getaddrinfo возвращает список адресов, назначенных серверу, и клиент пытается поочередно подключиться по каждому из них до тех пор, пока ему не удастся установить соединение. Это гарантирует, что клиент, поддерживающий, например, только IP версии 4 (IPv4), соединится с сервером, которому могли быть назначены как IPv4-, так и IPv6-адpeca, по соответствующему IPv4-адpecy.

Установив соединение, клиент может посылать и принимать данные через свой сокет, используя, например, recv и send. Клиент, не ориентированный на логические соединения (connectionless client), указывает удаленный адрес через эквивалентные функции API, не ориентированного на логические соединения; в данном случае — через sendto и recvfrom соответственно.

Функционирование Winsock на серверной стороне

Последовательность операций серверного приложения отличается от таковой для клиентского. После инициализации Winsock API сервер создает сокет и выполняет его привязку к локальному адресу через bind. Как и в случае клиентского приложения, тип адреса (по TCP/IP, TCP/IP с IP версии 6 или какому-то другому протоколу) выбирается серверным приложением.

Если сервер ориентирован на логические соединения, он выполняет на сокете операцию listen, указывая число соединений, которое он может поддерживать на этом сокете. Далее он выполняет операцию accept, чтобы клиент мог подключиться к сокету. При наличии ждущего запроса на соединение вызов accept завершается немедленно. B ином случае он завершается лишь после поступления запроса на соединение. После того как соединение установлено, функция accept возвращает новый сокет, представляющий серверную сторону соединения. Сервер может выполнять операции приема и передачи данных с помощью таких функций, как, например, recv и send. Рис. 13-3 иллюстрирует коммуникационную связь между клиентом и сервером Winsock, ориентированными на логические соединения.

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

Расширения Winsock

C точки зрения программирования для Windows, сильной стороной Winsock API является его интеграция с механизмом Windows-сообщений. Winsock-приложение может использовать преимущества такой интеграции для выполнения асинхронных операций с сокетом и приема уведомления о завершении операции через стандартное Windows-сообщение или функцию обратного вызова. Это упрощает разработку Windows-приложений, поскольку позволяет отказаться от многопоточности и синхронизирующих объектов для поддержки сетевого ввода-вывода и реакции на пользовательский ввод или запросы диспетчера окон на обновление окон приложения.

Кроме вспомогательных функций, прямо соответствующих функциям, реализованным в BSD Sockets, Microsoft добавила несколько функций, не входящих в стандарт Winsock. Две из них, AcceptEx и TransmitFile, стоят того, чтобы привести здесь их описание, так как благодаря им многие Web-серверы под управлением Windows достигают высокой производительности. AcceptEx является версией функции accept, которая в процессе установления соединения с клиентом возвращает адрес и первое сообщение клиента. AcceptEx дает возможность серверному приложению подготовиться к серии операций accept для последующей обработки множества входящих соединений. A это позволяет Web-серверу избежать выполнения сразу нескольких Winsock-функций.

Установив соединение с клиентом, Web-сервер обычно посылает ему файл, например Web-страницу. Реализация функции TransmitFile интегрирована с диспетчером кэша, что позволяет серверу посылать файл непосредственно из кэша файловой системы. Такая пересылка данных называется нулевым копированием (zero-сору), поскольку в этом случае серверу не приходится обращаться к файловым данным: он просто указывает описатель файла и диапазон пересылаемых байтов. Кроме того, функция TransmitFile позволяет серверу присоединять к началу или концу файла дополнительные данные. Это дает ему возможность посылать заголовочную информацию, например имя Web-сервера и поле, в котором указывается размер посылаемого сообщения. Internet Information Services (IIS), входящая в комплект поставки Windows, использует как AcceptEx, так и TransmitFile.

B Windows XP и Windows Server 2003 добавлен целый набор других, многофункциональных API-функций, в том числе ConnectEx, DisconnectEx и TransmitPackets. ConnectEx устанавливает соединение и посылает первое сообщение по этому соединению. DisconnectEx закрывает соединение и разрешает повторное использование описателя сокета, представляющего данное соединение, в вызове AcceptEx или ConnectEx. Наконец, TransmitPackets — полный аналог TransmitFile с тем исключением, что позволяет передавать не только файловые данные, но и данные, находящиеся в памяти.

Принципы расширения Winsock

Winsock является расширяемым API, поскольку сторонние разработчики могут добавлять провайдеры транспортных сервисов (transport service providers, TSP), организующие интерфейсы Winsock и другими протоколами или уровнями поверх существующих протоколов (это позволяет реализовать такую функциональность, как поддержка прокси). Сторонние разработчики также могут добавлять провайдеры пространств имен (namespace service providers), дополняющие механизмы разрешения имен в Winsock. Такие компоненты подключаются к Winsock через его интерфейс провайдеров сервисов (service provider interface, SPI). Если какой-то TSP регистрируется в Winsock, последний реализует на его основе функции сокета (вроде connect и accepf) для тех типов адресов, которые указаны этим провайдером как поддерживаемые. Никаких ограничений на то, как TSP реализует функции, не налагается, но такая реализация обычно требует взаимодействия с драйвером транспорта в режиме ядра.

Требование к любому клиент-серверному приложению, использующему Winsock, заключается в следующем: сервер должен сделать свой адрес доступным клиентам, чтобы они могли подключаться к серверу. Для стандартных сервисов, выполняемых в TCP/IP, с этой целью используются так называемые общеизвестные адреса. Если браузер знает имя компьютера, на котором работает Web-сервер, он может подключиться к нему, указав общеизвестный адрес Web-сервера (к IP-адресу сервера добавляется строка «:80» — номер HTTP-порта). Провайдеры пространств имен позволяют серверам регистрировать свое присутствие и другими способами. Например, провайдер пространства имен мог бы на серверной стороне регистрировать адрес сервера в Active Directory, а на клиентской — искать его в Active Directory. Провайдеры пространств имен обеспечивают эту функциональность Winsock, реализуя такие стандартные Winsock-функции разрешения имен, как getaddrinfo (заменяет gethostbyname) и getnameinfo.

ЭКСПЕРИМЕНТ: просмотр провайдеров сервисов Winsock

Утилита Windows Sockets Configuration (Sporder.exe), входящая в Platform SDK, показывает зарегистрированные в Winsock провайдеры транспортных сервисов и пространств имен и позволяет изменять порядок перечисления TSP Например, если в системе имеется два провайдера транспортных сервисов TCP/IP, то первым в списке идет TSP по умолчанию для Winsock-приложений, использующих протокол TCP/IP. Ha иллюстрации показано окно Sporder, в котором перечислены зарегистрированные TSP

Реализация Winsock

Реализация Winsock представлена на рис. 13-4. Его программный интерфейс поддерживается библиотекой Ws2_32.dll (\Windows\System32\Ws2_32.dll), которая обеспечивает приложениям доступ к функциям Winsock. Для операций над именами и сообщениями Ws2_32.dll вызывает сервисы TSP и провайдеров пространств имен. Библиотека Mswsock.dll выступает в роли TSP для протоколов, поддерживаемых Microsoft в Winsock. Она взаимодействует с драйверами протоколов режима ядра с помощью вспомогательных библиотек Winsock (Winsock Helpers), специфичных для конкретного протокола. Например, Wshtcpip.dll — вспомогательная библиотека TCP/IP. B Mswsock.dll (\Windows\System32\Mswsock.dll) реализованы такие расширения Winsock, как функции TransmitEile,AcceptEx и WSARecvEx. Windows поставляется со вспомогательными библиотеками для TCP/IP, TCP/IP с IPv6, AppleTalk, IPX/SPX, ATM и IrDA (Infrared Data Association), а также с провайдерами пространств имен для DNS (TCP/IP), Active Directory и IPX/SPX.

Рис. 13-4. Реализация Winsock

Подобно API именованных каналов и почтовых ящиков Winsock интегрируется с Windows-моделью ввода-вывода и использует для представления co-кетов описатели файлов. Для этого нужна помощь со стороны драйвера файловой системы режима ядра, поэтому, реализуя функции на основе сокетов, Msafd.dll использует сервисы AFD (Ancillary Function Driver) (\Windows\System32\Drivers\Afd.sys). AFD является клиентом TDI и выполняет сетевые операции с использованием сокетов, например посылает и принимает сообщения, отправляя TDI IRP-пакеты драйверам протокола. AFD не запрограммирован на использование определенных драйверов протоколов — вместо этого Msafd.dll уведомляет AFD о протоколе, используемом для сокета, и в результате AFD может открыть объект «устройство», представляющий этот протокол.

Windows Sockets Direct

Windows Sockets Direct (WSD) — это интерфейс, позволяющий в Winsock-приложениях без всякой модификации использовать преимущества сетей устройств хранения данных (System Area Networks, SAN). Высокопроизводительные SAN идеальны для самых разнообразных применений — от распределенных вычислений до трехуровневых архитектур электронной коммерции вроде показанной на рис. 13-5. B данной системе сети SAN соединяют Web-серверы (презентационный Web-уровень) с серверами бизнес-логики и с серверами базы данных, что обеспечивает высокоскоростную передачу данных между различными уровнями обработки информации. Поддержка WSD имеется в Windows 2003 и Windows 2000 Data Center Server, а также в Windows 2000 Advanced Server c Service Pack (SP) 2 и выше.

SAN-соединения

Высокая производительность SAN обычно достигается за счет специализированных сетевых соединений и коммутационного оборудования. K наиболее распространенным типам SAN-соединений относятся InfiniBand, Gigabit Ethernet, FiberChannel и различные фирменные (закрытые) решения. Физическая память, разделяемая двумя компьютерами, тоже может служить SAN-соединением.

Коммутационное оборудование SAN реализует немаршрутизируемый протокол, предоставляющий TCP-эквивалентные гарантии, в частности надежную доставку сообщений в правильном порядке. Эти аппаратные средства также поддерживают механизм SAN, называемый удаленным прямым доступом к памяти (Remote Direct Memory Access, RDMA); этот механизм позволяет напрямую передавать сообщения из физической памяти компьютера-источника в физическую память компьютера-получателя без промежуточной операции копирования, которая обычно выполняется на стороне, принимающей сообщения. Благодаря этому RDMA освобождает процессор и шину памяти от лишней нагрузки, связанной с операцией копирования.

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

Архитектура WSD

Большинство реализаций SAN требуют модификации приложений для взаимодействия с сетевыми протоколами SAN и использования преимуществ аппаратно-реализованных протоколов и механизмов SAN вроде RDMA, но WSD позволяет любому Winsock-приложению, работающему по протоколу TCP, задействовать возможности SAN без такой модификации. Само название WSD подчеркивает, что он обеспечивает приложениям прямой доступ к оборудованию SAN, в обход стека TCP/IP. A сокращение пути передачи данных повышает производительность приложений в 2–2,5 раза.

Такое сокращение достигается за счет использования программного коммутатора, размещаемого на уровень ниже Winsock DLL, как показано на рис. 13-6. Этот коммутатор переадресует сетевые операции SAN провайдеру сервисов Winsock (Winsock service provider, WSP), который предоставляется производителем SAN. WSP служит эквивалентом NDIS-драйвера, работающим в пользовательском режиме, и может проецировать аппаратные регистры SAN на память пользовательского режима, а затем манипулировать оборудованием без участия компонентов режима ядра. Однако некоторые операции все же требуют поддержки со стороны таких компонентов, например для проецирования содержимого аппаратных регистров на память пользовательского режима; эта поддержка тоже предоставляется производителем оборудования SAN. Наконец, производитель SAN предоставляет минипорт-драйвер NDIS, выступающий в роли интерфейса между стеком TCP/IP и оборудованием SAN для приложений, которые используют сетевые средства Winsock, не поддерживаемых SAN на аппаратном уровне.

Remote Procedure CaII (RPC)

RPC — стандарт сетевого программирования, разработанный в начале 80-x. Организация Open Software Foundation (теперь — The Open Group) сделала RPC частью стандарта OSF DCE (Distributed Computing Environment). Несмотря на наличие второго стандарта RPC, SunRPC, реализация RPC от Microsoft совместима со стандартом OSF DCE. RPC, опираясь на другие сетевые API (именованные каналы или Winsock), предоставляет альтернативную модель программирования, в какой-то мере скрывающую детали сетевого программирования от разработчика приложений.

Функционирование RPC

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

Сетевое программное обеспечение традиционно базируется на модели обработки ввода-вывода. B Windows, например, сетевая операция начинается с того, что приложение выдает запрос на удаленный ввод-вывод. Операционная система обрабатывает запрос, передавая его редиректору, который действует в качестве удаленной файловой системы, обеспечивая прозрачное взаимодействие клиента с удаленной файловой системой. Редиректор передает запрос удаленной файловой системе, а после того как удаленная система выполнит запрос и вернет результаты, локальная сетевая плата генерирует прерывание. Ядро обрабатывает это прерывание, и исходная операция ввода-вывода завершается, возвращая результаты вызывающей программе.

RPC использует совершенно другой подход. Приложения RPC похожи на другие структурированные приложения: у них есть основная программа, которая для выполнения специфических задач вызывает процедуры или библиотеки процедур. Отличие приложений RPC от обычных программ в том, что некоторые библиотеки процедур в приложениях RPC выполняются на удаленных компьютерах, а некоторые — на локальном (рис. 13-7).

Для приложения RPC все процедуры кажутся локальными. Иначе говоря, вместо того чтобы заставлять программиста писать код для передачи запросов на вычисления или ввод-вывод по сети, работы с сетевыми протоколами, обработки сетевых ошибок, ожидания результатов и т. д., программное обеспечение RPC выполняет все эти задачи автоматически. Кроме того, механизм RPC в Windows работает с любыми транспортами, которые имеются в системе.

Создавая приложение RPC, программист решает, какие процедуры будут выполняться локально, а какие — удаленно. Допустим, обычная рабочая станция подключена по сети к суперкомпьютеру Cray или к специализированной машине, предназначенной для быстрого выполнения векторных вычислений. Если программист пишет программу, работающую с большими матрицами, то с точки зрения производительности имело бы смысл переложить математические вычисления на удаленный компьютер, написав программу в виде приложения RPC.

Функционирует приложение RPC следующим образом. B процессе своей работы оно вызывает как локальные процедуры, так и процедуры, отсутствующие на локальной машине. Для обработки последнего случая приложение связывается с локальной DLL, которая содержит интерфейсные процедуры (stub procedures) для всех удаленных процедур. B простой программе интерфейсные процедуры статически связываются с приложением, но в компоненте большего размера они включаются в отдельные DLL. B DCOM обычно применяется последний метод. Интерфейсная процедура имеет то же имя и тот же интерфейс, что и удаленная процедура, но вместо выполнения соответствующей операции она просто преобразует переданные ей параметры для передачи по сети — такой процесс называется маршалингом (marshaling). Маршалинг заключается в упорядочении параметров и их упаковке в определенном формате.

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

Кроме интерфейса, основанного на описанном здесь синхронном вызове процедур, RPC в Windows также поддерживает асинхронный RPC (asynchronous RPC). Он позволяет приложению RPC вызывать функцию и, не дожидаясь ее выполнения, продолжать свою работу. Ha это время приложение может перейти к выполнению другого кода. Когда от сервера придет ответ, библиотека RPC периода выполнения уведомит клиент о завершении операции. При этом используется механизм уведомления, запрошенный клиентом. Если клиент выбрал для уведомления синхронизирующий объект «событие», он ждет его перехода в свободное состояние, вызвав функцию WaitForSingle-Object или WaitForMultipleObject. Если клиент предоставляет APC (Asynchronous Procedure Call), библиотека RPC периода выполнения ставит APC в очередь потока, выполняющего RPC-функцию. Если же клиент использует в качестве механизма уведомления порт завершения ввода-вывода, он должен вызвать GetQueuedCompletionStatus, чтобы узнать об окончании работы этой функции. Наконец, клиент может опрашивать библиотеку RPC периода выполнения о ходе выполнения операции, вызывая RcpAsyncGetCallStatus.

Помимо библиотеки периода выполнения в Microsoft RPC входит компилятор MIDL (Microsoft Interface Definition Language). Этот компилятор упрощает создание приложений RPC Программист пишет набор обычных прототипов функций (предполагается, что он использует язык C или C++), описывающих удаленные процедуры, а затем помещает их в какой-либо файл. Далее он добавляет к этим прототипам нужную дополнительную информацию, например уникальный для сети идентификатор пакета процедур, номер версии и атрибуты, указывающие, являются ли параметры входными, выходными или и теми, и другими одновременно. B конечном счете программист получает файл на языке IDL (Interface Definition Language).

Подготовленный IDL-файл транслируется компилятором MIDL, который создает интерфейсные процедуры для клиентской и серверной сторон, а также заголовочные файлы, включаемые в приложение. Когда клиентское приложение связывается с файлом интерфейсных процедур, компоновщик разрешает все ссылки на удаленные процедуры. Аналогичным образом удаленные процедуры устанавливаются на серверной машине. Программист, который намерен вызывать существующее приложение RPC, должен написать только клиентскую часть программы и скомпоновать ее с локальной библиотекой RPC периода выполнения.

Библиотека RPC периода выполнения использует для взаимодействия с транспортным протоколом универсальный интерфейс провайдеров трансnopmaRPC (RPC transport provider interface). Этот интерфейс служит тонкой прослойкой между механизмом RPC и транспортом, которая увязывает операции RPC с функциями, предоставляемыми транспортом. RPC в Windows реализует DLL-модули провайдеров транспорта для именованных каналов, NetBIOS, SPX, TPC/IP и UDP. B Windows Server 2003 провайдер транспорта NetBIOS изъят, но добавлен провайдер для HTTR Аналогичным образом RPC поддерживает работу с различными средствами сетевой защиты.

ПРИМЕЧАНИЕ B Windows 2000 можно написать новые DLL-модули провайдеров для поддержки дополнительных транспортов, но, начиная с Windows XP, встраивание дополнительных DLL провайдеров не поддерживается.

Большинство сетевых служб Windows является приложениями RPC, а это значит, что они могут вызываться как локальными процессами, так и процессами на удаленных машинах. Таким образом, удаленный клиентский компьютер может обращаться к службам сервера для просмотра списка общих ресурсов, открытия файлов, записи данных в очереди печати или добавления пользователей на этом сервере, либо он может вызывать Messenger Service (Службу сообщений) для посылки сообщений (конечно, при наличии соответствующих прав доступа).

Сервер может регистрировать свое имя по адресу, который будет доступен клиенту при поиске. Эта возможность, называемая публикацией имени сервера, реализована в RPC и интегрирована с Active Directory. Если Active Directory не установлена, служба локатора имен возвращается к широковещательной рассылке с использованием NetBIOS. Это позволяет взаимодействовать с системами под управлением Windows NT 4 и дает возможность RPC функционировать на автономных серверах и рабочих станциях.

Защита в RPC

RPC интегрирован с компонентами поддержки защиты (security support providers, SSP), что позволяет клиентам и серверам RPC использовать аутентификацию и шифрование при коммуникационной связи. Когда серверу RPC требуется защищенное соединение, он сообщает библиотеке RPC периода выполнения, какую службу аутентификации следует добавить в список доступных служб аутентификации. A когда клиенту нужно использовать защищенное соединение, он выполняет привязку к серверу. Bo время привязки к серверу клиент должен указать библиотеке RPC службу аутентификации и нужный уровень аутентификации. Различные уровни аутентификации обеспечивают подключение к серверу только авторизованных клиентов, проверку каждого сообщения, получаемого сервером (на предмет того, послано ли оно авторизованным клиентом), контроль за целостностью RPC-сообщений и даже шифрование данных RPC-сообщений. Чем выше уровень аутентификации, тем больше требуется обработки. Клиент также может указывать имя участника безопасности (principal name) для сервера. Участник безопасности (principal) — это сущность, распознаваемая системой защиты RPC Сервер должен зарегистрироваться в SSP под именем участника безопасности, специфичным для SSP.

SSP берет на себя все, что связано с аутентификацией и шифрованием при коммуникационной связи, не только для RPC, но и для Winsock. B Windows несколько встроенных SSP, в том числе Kerberos SSP, реализующий аутентификацию Kerberos v5, SChannel (Secure Channel), реализующий Secure Sockets Layer (SSL), и протоколы TLS (Transport Layer Security). Если SSP не указан, программное обеспечение RPC использует встроенные средства защиты нижележащего транспорта. Одни транспорты, в частности именованные каналы и локальный RPC, имеют такие средства защиты, а другие, например TCP, — нет. B последнем случае RPC при отсутствии указанного SSP выдает небезопасные вызовы.

Еще одна функция защиты RPC позволяет серверу подменять клиент через функцию RpcImpersonateClient. Когда сервер заканчивает выполнение операций, потребовавших подмены клиента собой, он возвращается к использованию своих идентификационных данных защиты вызовом функции RpcRevertToSelf или RpcRevertToSelJEx (подробнее о подмене, или олицетворении, см. главу 8).

Реализация RPC

Реализация RPC изображена на рис. 13-8, где показано, что приложение на основе RPC связано с библиотекой RPC периода выполнения (\Windows\Sys-tem32\Rpcrt4.dll). Последняя предоставляет для интерфейсных RPC-функций приложений функции маршалинга, а также функции для приема и передачи упакованных данных. Библиотека RPC периода выполнения включает процедуры поддержки RPC-взаимодействия через сеть и разновидность RPC под названием локальный RPC. Локальный RPC позволяет двум процессам взаимодействовать в одной системе, при этом библиотека RPC в качестве сетевого API использует LPC в режиме ядра (об LPC см. главу 3). Когда RPC-взаимодей-ствие осуществляется между удаленными системами, библиотека RPC использует API-функции Winsock, именованного канала или Message Queuing.

ПРИМЕЧАНИЕ Message Queuing в Windows Server 2003 не поддерживается в качестве транспорта.

Подсистема RPC (RPCvSS) (\Windows\System32\Rpcss.dll) реализована в виде Windows-сервиса. RPCSS сама является приложением RPC, которое взаимодействует со своими экземплярами на других системах для поиска имен, регистрации и динамического подключения конечной точки (dynamic end-point mapping). (Для упрощения на рис. 13-8 не показана связь RPCSS с библиотекой RPC периода выполнения.)

API-интерфейсы доступа к Web

Чтобы упростить разработку Интернет-приложений, в Windows предусмотрены клиентские и серверные API-интерфейсы доступа к Интернету. C помощью этих API приложения могут предоставлять и использовать сервисы Gopher, FTP и HTTP, не зная внутреннего устройства соответствующих протоколов. Клиентские API включают Windows Internet, также называемый WinInet (позволяет приложениям взаимодействовать с протоколами Gopher, FTP и HTTP), и WinHTTP (дает возможность приложениям взаимодействовать с протоколом HTTP). B определенных ситуациях WinHTTP удобнее WinInet. HTTP — это серверный API, введенный в Windows Server 2003 для поддержки разработки серверных Web-приложений.

WinInet

WinInet поддерживает протоколы Gopher, FTP и HTTP версий 1.0 и 1.1. Этот API делится на наборы под-API, специфичные для каждого протокола. Используя API-функции FTP вроде InternetConnect для подключения к FTP-cep-веру, FtpFindFirstFile и FtpFindNextFile для перечисления содержимого FTP-каталога, а также FtpGetFile и FtpPutFile для приема и передачи файлов, разработчик приложения может не задумываться о деталях, связанных с установлением соединения и форматированием TCP/IP-сообщений для протокола FTP API-функции Gopher и HTTP обеспечивают аналогичный уровень абстракции. WinInet применяется базовыми компонентами Windows, например Windows Explorer и Internet Explorer.

WinHTTP

Текущая версия WinHTTP API — 5.1; она доступна в Windows 2000 с Service Pack 3, в Windows XP и Windows Server 2003- Этот API обеспечивает абстракцию протокола HTTP 1.1 для клиентских HTTP-приложений по аналогии с HTTP API в WinInet. Однако, если WinInet HTTP API предназначен для интерактивных клиентских приложений, то WinHTTP API — для серверных приложений, взаимодействующих с HTTP-серверами. Серверные приложения часто реализуются как Windows-службы без UI, поэтому им не нужны диалоговые окна, которые позволяют выводить API-функции WinInet. Кроме того, WinHTTP API лучше масштабируется и предоставляет средства защиты вроде подмены потоков, недоступные в WinInet API.

HTTP

C помощью HTTP API, реализованного в Windows Server 2003, серверные приложения могут регистрироваться на прием HTTP-запросов с определенных URL, принимать такие запросы и передавать HTTP-ответы. HTTP API включает поддержку SSL (Secure Sockets Layer), чтобы приложения могли обмениваться данными по защищенным HTTP-соединениям. Этот API поддерживает кэширование на серверной стороне, модели синхронного и асинхронного ввода-вывода, а также адресацию по IPv4 и IPv6. HTTP API используется IIS версии 6 (поставляется с Windows Server 2003).

HTTP API, к которому приложения обращаются через библиотеку Httpapi.dll, опирается на драйвер Http.sys режима ядра. Http.sys запускается по требованию при первом вызове HttpInitialize любым приложением. Функция HttpCreateHttpHandle позволяет создавать закрытую очередь запросов, а функция HttpAddUrl — указывать URL-адреса, по которым приложение собирается принимать запросы для обработки. Используя очереди запросов и их зарегистрированные URL, Http.sys дает возможность обслуживать НТТР-запросы на одном порту, например 80, более чем одному приложению.

HttpReceiveHttpRequest принимает входящие запросы, направленные по зарегистрированным URL, zHttpSendHttpRespome передает HTTP-ответы. Обе функции работают в асинхронном режиме, так что приложение может определять, закончена ли какая-то операция, используя GetOverlappedResult или порты завершения ввода-вывода.

Приложения могут использовать Http.sys для кэширования данных в неподкачиваемой физической памяти, вызывая HttpAddToFragmentCache и сопоставляя имя фрагмента с кэшируемыми данными. Ддя выделения неспроецированных страниц физической памяти Http.sys запускает функцию MmAllocate-PagesForMdl, принадлежащую диспетчеру памяти. Когда Http.sys требуется сопоставление виртуального адреса с физической памятью, описываемой элементом кэша (например, если Http.sys копирует данные в кэш или передает их из кэша), он вызывает MmMapLockedPagesSpecifyCache, а по окончании операций — MmUnmapLockedPages. Http.sys хранит кэшируемые данные до тех пор, пока приложение не объявит их недействительными или пока не истечет срок их актуальности, заданный приложением. Http.sys также усекает кэшируемые данные при пробуждении рабочего потока из-за перехода в свободное состояние события, уведомляющего о малом объеме памяти (информацию об этом событии см. в главе 7). Если при вызове HttpSendHttpResponse приложение указывает одно или несколько имен фрагментов, Http.sys передает указатель на данные, кэшируемые в физической памяти, драйверу TCP/ IP и тем самым исключает лишнюю операцию копирования.

Именованные каналы и почтовые ящики

Именованные каналы и почтовые ящики — это API, изначально разработанные Microsoft для OS/2 LAN Manager и впоследствии перенесенные в Windows NT Именованные каналы обеспечивают надежную двустороннюю связь, тогда как почтовые ящики — ненадежную одностороннюю передачу данных. Преимущество почтовых ящиков — в поддержке широковещательной передачи. Оба API используют систему защиты Windows, что позволяет серверам контролировать, какие клиенты могут подключаться к ним.

Серверы назначают именованным каналами и их клиентам имена в соответствии с универсальными правилами именования (Universal Naming Convention, UNC), которые обеспечивают независимый от протоколов способ идентификации ресурсов в Windows-сетях. O реализации UNC-имен мы расскажем позже.

Функционирование именованных каналов

Коммуникационная связь по именованному каналу включает сервер именованного канала и клиент именованного канала. Сервером именованного канала является приложение, создающее именованный канал, к которому подключаются клиенты. Формат имени канала выглядит так: \\Cepвep\Pipe\ ИмяКанала. Элемент Сервер указывает компьютер, на котором работает сервер именованного канала. Элемент Pipe должен быть строкой «Pipe», а Имя-Канала — уникальное имя, назначенное именованному каналу. Уникальная часть имени канала может включать подкаталоги. Пример такого UNC-име-ни канала — \\MyComputer\Pipe\MyServerApp\ConnectionPipe.

Для создания именованного канала сервер использует Windows-функцию CreateNamedPipe. Одним из входных параметров этой функции является указатель на имя канала в форме \\.\Рiре\ИмяКанала, где «\\.\» — псевдоним локального компьютера, определенный в Windows. Функция также принимает необязательный дескриптор защиты, запрещающий несанкционированный доступ к именованному каналу, флаг, указывающий, должен ли канал быть двусторонним или односторонним, параметр, определяющий максимальное число одновременных соединений по данному каналу, и флаг режима работы канала (побайтовой передачи или передачи сообщений).

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

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

Для подключения к серверу клиенты именованного канала используют Windows-функцию CreateFile или CallNamedPipe, указывая при вызове имя созданного сервером канала. Если сервер вызывает функцию ConnectNamedPipe, профиль защиты клиента и запрошенные им права доступа к каналу (для чтения или записи) сравниваются с дескриптором защиты канала (подробнее об алгоритмах проверки прав доступа см. главу 8). Если клиенту разрешен доступ к именованному каналу, он получает описатель, представляющий клиентскую сторону именованного канала, и функция ConnectNamedPipe, вызванная сервером, завершается.

После того как соединение по именованному каналу установлено, клиент и сервер могут использовать его для чтения и записи данных через Windows-функции ReadFile и WriteFile. Именованные каналы поддерживают как синхронную, так и асинхронную передачу сообщений. Взаимодействие клиента и сервера через именованный канал показано на рис. 13-9.

Уникальная особенность API именованного канала заключается в том, что он позволяет серверу олицетворять клиент с помощью функции ImpersonateNamedPipeClient. O том, как используется олицетворение в клиент-серверных приложениях, см. раздел «Олицетворение» главы 8.

Функционирование почтового ящика

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

Как и именованные каналы, почтовые ящики интегрированы с Windows API. Сервер почтового ящика создает почтовый ящик вызовом CreateMailslot. Входным параметром этой функции является имя в форме «\\.\Mailslot\ИмяПочтовогоЯщика». Сервер может создавать почтовые ящики только на той машине, на которой он работает, а назначаемые им имена почтовых ящиков могут включать подкаталоги. CreateMailslot также принимает необязательный дескриптор защиты, контролирующий доступ клиента к почтовому ящику. Описатели, возвращаемые CreateMailslot, являются перекрытыми.

Это означает, что операции с использованием таких описателей (например, рассылка и получение сообщений) выполняются асинхронно.

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

Клиенты почтового ящика используют формат именования, аналогичный применяемому клиентами именованных каналов, за исключением вариаций, необходимых для широковещательной передачи сообщений всем почтовым ящикам с данным именем в домене клиента или в другом указанном домене. Чтобы послать сообщение в определенный экземпляр почтового ящика, клиент вызывает функцию CreateFile, указывая имя, специфичное для компьютера, например «\\Сервер\Mailslot\ИмяПочтовогоЯщика». (Для представления локального компьютера клиент задает «\\.\».) Если клиент хочет получить описатель, представляющий все почтовые ящики с заданным именем в домене, членом которого он является, он указывает имя в формате «\\*\Mailslot\ ИмяПочтовогоЯщика». Для широковещательной передачи во все почтовые ящики с заданным именем в другом домене используется имя в формате «\\ИмяДомена\Mailslot\ИмяПочтовогоЯщика».

Получив описатель, представляющий клиентскую сторону почтового ящика, клиент посылает сообщения через функцию WriteFile. Реализация почтовых ящиков допускает широковещательную передачу сообщений длиной не более 425 байтов. Если длина сообщения превышает 425 байтов, почтовый ящик использует механизм надежной коммуникационной связи, требующий соединения клиента с сервером по типу «один к одному», что исключает возможность широковещательной передачи. Другая (довольно странная) особенность почтовых ящиков — урезание сообщений с исходной длиной в 425 или 426 байтов до 424 байтов. Таким образом, почтовые ящики непригодны для рассылки сообщений, длина которых превышает 424 байта. Ha рис. 13–10 показан пример широковещательной передачи клиентского сообщения на несколько серверов почтовых ящиков в пределах домена.

Реализация именованных каналов и почтовых ящиков

O тесной интеграции функций именованных каналов и почтовых ящиков с Windows свидетельствует тот факт, что все они реализованы в Kernel32.dll. ReadFile и WriteFile, используемые приложениями для обмена сообщениями через именованные каналы и почтовые ящики, являются основными Windows-функциями ввода-вывода. CreateFile, с помощью которой клиент открывает именованный канал или почтовый ящик, также является стандартной Windows-функцией ввода-вывода. Однако имена, указываемые приложениями при использовании именованных каналов и почтовых ящиков, относятся к пространству имен под управлением драйверов файловых систем именованных каналов (\Windows\System32\Drivers\Npfs.sys) и почтовых ящиков (\Windows\System32\Drivers\Msfs.sys), как показано на рис. 13–11. Драйвер файловой системы именованных каналов создает объект «устройство» \Device\NamedPipe и символьную ссылку на этот объект с именем \Global??\Pipe (\??\Pipe в Windows 2000), а драйвер файловой системы почтовых ящиков создает объект «устройство» \Device\Mailslot и символьную ссылку \Global??\Mailslot (\??\Mailslot в Windows 2000), которая указывает на этот объект. (O каталоге \Global?? диспетчера объектов см. главу 3.) Префикс «\\.\» в именах «\\.\Pipe\…» и «\\.\Mailslot\…», передаваемых CreateFile, транслируется в «\Global??\», чтобы эти имена разрешались через символьную ссылку на объект «устройство». Специальные функции CreateNamedPipe и CreateMailslot используют соответствующие функции ядра NtCreateNamed-PipeFile и NtCreateMailslotFile.

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

• Используя функции защиты режима ядра, FSD реализуют для именованных каналов и почтовых ящиков стандартную защиту Windows.

• Поскольку FSD интегрированы с пространством имен диспетчера объектов, приложения могут открывать именованный канал или почтовый ящик вызовом функции CreateFile.

• Приложения могут взаимодействовать с именованными каналами и почтовыми ящиками через Windows-функции вроде ReadFile и WriteFile.

• FSD полагаются на диспетчер объектов в поддержке счетчиков описателей и ссылок для объектов «файл», представляющих именованные каналы и почтовые ящики.

• FSD могут реализовать собственные пространства имен каналов и почтовых ящиков, допускающие указание подкаталогов.

Так как взаимодействие через сеть при разрешении имен именованных каналов и почтовых ящиков осуществляется через редиректор, FSD при этом неявно используют протокол CIFS (Common Internet File System). Поскольку CIFS способен работать с TCP/IP, TCP/IP с IPv6 и IPX, именованные каналы и почтовые ящики доступны приложениям, выполняемым в системах, где установлен хотя бы один общий такой протокол. (Сведения о CIFS см. в главе 12.)

ЭКСПЕРИМЕНТ: просмотр пространства имен именованных каналов и наблюдение за активностью таких каналов

Открыть корневой каталог FSD именованных каналов и перечислить его содержимое с помощью Windows API нельзя — для этого нужно воспользоваться сервисами встроенного API. Утилита PipeList (www.sys- internals.com) перечисляет именованные каналы, определенные на компьютере, число созданных экземпляров канала с данным именем и максимальное число каналов, заданное сервером при вызове Create-NamedPipe. Вот пример вывода PipeList.

Из этого листинга ясно, что некоторые системные компоненты используют именованные каналы как механизм связи. Например, канал InitShutdown создан Winlogon для приема удаленных команд на завершение работы, а канал SecLogon — сервисом SecLogon для выполнения операций входа в интересах утилиты Runas. Определить, каким из процессов открыт каждый из этих каналов, можно с помощью утилиты Process Explorer (wwsysinternals.com). Заметьте, что значение Max Instances, равное -1, означает, что на число экземпляров канала с данным именем не накладывается никаких ограничений.

Драйвер фильтра файловой системы Filemon (wwwsysinternals.com) способен подключаться к драйверу файловой системы Npfs.sys или Msfs.sys, что позволяет ему наблюдать за активностью всех именованных каналов или почтовых ящиков в системе. Для подключения Filemon к соответствующему драйверу выберите из меню Drives команду Named Pipes или Mail Slots. Ha иллюстрации ниже показано окно Filemon, в котором сообщается об активности именованных каналов, вызываемой двойным щелчком значка My Network Places (Мое сетевое окружение) на рабочем столе. Заметьте, что сообщения передаются через именованные каналы LSASS и службы рабочей станции.

NetBIOS

До начала 90-х годов NetBIOS (Network Basic Input/Output System) API был самым популярным интерфейсом программирования для персональных компьютеров. NetBIOS поддерживал связь как надежную, ориентированную на логические соединения, так и ненадежную, не требующую логических соединений. Windows поддерживает NetBIOS для совместимости с унаследованными приложениями. Microsoft не рекомендует разработчикам приложений использовать NetBIOS, поскольку существуют куда более гибкие и переносимые API, например именованные каналы и Winsock. NetBIOS в Windows поддерживается протоколами TCP/IP и IPX/SPX.

NetBIOS-имена

NetBIOS использует правила именования, согласно которым компьютерам и сетевым службам назначаются 16-байтовые имена, называемые NetBIOS-именами; 16-й байт в NetBIOS-имени интерпретируется как модификатор, который указывает, является ли имя уникальным или групповым.* Уникальное NetBIOS-имя может быть назначено только одному компьютеру или службе в сети, а групповое имя — нескольким компьютерам или службам. Адресуя сообщение на групповое имя, клиент может вести широковещательную рассылку.

Windows — для поддержки взаимодействия с системами под управлением Windows NT 4 и потребительских версий Windows — автоматически определяет NetBIOS-имя для домена как первые 15 байтов DNS-имени (Domain Name System), назначенного домену администратором. Например, домен mspress.microsoft.com получает NetBIOS-имя mspress. Аналогичным образом Windows требует, чтобы во время установки администратор назначил каждому компьютеру NetBIOS-имя.

Еще одна концепция, используемая в NetBIOS, — номера адаптеров LAN (LANA). Номер LANA присваивается каждому NetBIOS-совместимому протоколу, расположенному на более высоком уровне, чем сетевой адаптер. Так, если в компьютере установлено два сетевых адаптера, доступных для TCP/ IP и NWLink, то в результате будет назначено четыре номера LANA. Номера LANA важны, поскольку приложения NetBIOS должны явно закреплять имена своих сервисов за каждым LANA, через который они готовы принимать клиентские соединения. Если приложение ждет соединений с клиентами по определенному имени, клиенты получат доступ к приложению только через протоколы, для которых зарегистрировано это имя.

Разрешение NetBIOS-имен в IP-адреса описывается в разделе «Windows Internet Name Service» далее в этой главе.

* Здесь авторы допускают неточность. 16-й байт NetBIOS-имени прежде всего является идентификатором типа ресурса. Он указывает сетевой компонент или службу, которая назначила это NetBIOS-имя компьютеру, пользователю или домену. Hy и, кроме того, NetBIOS-имя может быть зарегистрировано как уникальное (принадлежащее одному владельцу) или как групповое (принадлежащее нескольким владельцам). — Прим. перев.

Функционирование NetBIOS

Серверное приложение NetBIOS использует NetBIOS API для перечисления LANA, имеющихся в системе, и назначения каждому из них NetBIOS-имени, представляющего сервис приложения. Если сервер требует логических соединений, он выполняет NetBIOS-команду listen для ожидания попыток подключения клиентов. После того как соединение с клиентом установлено, сервер выполняет функции NetBIOS для передачи и приема данных. Аналогичным образом осуществляется и связь, не требующая логических соединений, но сервер просто принимает сообщения, не устанавливая соединение.

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

NetBIOS состоит из набора функций, но все они действуют через один и тот же интерфейс — Netbios. Это наследие тех времен, когда NetBIOS реализовали в виде прерывания MS-DOS. Приложение NetBIOS выполняло прерывание MS-DOS и передавало NetBIOS структуру данных, где задавались все параметры нужной команды. B итоге функция Netbios в Windows принимает единственный параметр, который представляет собой структуру данных с параметрами, специфичными для запрошенного приложением сервиса.

ЭКСПЕРИМЕНТ: просмотр NetBIOS-имен через Nbtstat

Для вывода списка активных сеансов в системе, кэшируемых сопоставлений NetBIOS-имен и IP-адресов, а также NetBIOS-имен, определенных на компьютере, можно использовать встроенную в Windows команду Nbtstat… Ниже приведен пример вывода этой команды с параметром — n, при указании которого выводится список NetBIOS-имен, определенных на компьютере.

Реализация NetBIOS API

Компоненты, реализующие NetBIOS API, показаны на рис. 13–12. Функция Netbios экспортируется приложениям из \Windows\System32\Netapi32.dll. Netapi32.dll открывает описатель драйвера режима ядра под названием эму-nnmopNetBlOS (\Windows\System32\Drivers\Netbios.sys) и выдает Windows-команды DeviceIoControlFile от имени приложения. Эмулятор NetBIOS транслирует команды NetBIOS в команды TDI, посылаемые драйверам протоколов.

Если приложение требует использовать NetBIOS поверх TCP/IP, то эмулятору NetBIOS нужен драйвер NetBT (\Windows\System32\Drivers\Netbt.sys). NetBT отвечает за поддержку семантики NetBIOS, присущей не TCP/IP, а NetBEUI (NetBIOS Extended User Interface), который включался в предыдущие версии Windows. Например, NetBIOS полагается на NetBEUI-поддержку режима передачи данных в виде сообщений и на средства разрешения имен, поэтому драйвер NetBT реализует их поверх протокола TCP/IP. Аналогичным образом драйвер NwLinkNB реализует семантику NetBIOS поверх IPX/SPX.

Другие сетевые API

B Windows входит еще несколько сетевых API, которые используются реже и расположены на более высоком уровне, чем уже рассмотренные API. Изучение всех этих API выходит за рамки книги, но четыре из них — RTC (Real-Time Communications), DCOM (Distributed Component Object Model), Message Queuing и UPnP (Universal Plug and Play) — достаточно важны для функционирования Windows и многих приложений и поэтому заслуживают краткого описания.

RTC

RTC Client API, доступный в Windows XP и Windows Server 2003, позволяет разработчикам создавать приложения, способные устанавливать многорежимные коммуникационные соединения и превращать персональный компьютер (ПК) в центр домашних или деловых коммуникаций. Голосовая и видеосвязь, мгновенный обмен сообщениями (Instant Messaging, IM), поддержка совместной работы — все это становится доступным в одном сеансе коммуникационной связи. Помимо сеансов связи между ПК, этот API позволяет устанавливать сеансы связи «ПК-телефон», «телефон-телефон» или только текстового IM. B сеансах связи между ПК также доступны совместное использование приложений (application sharing) и общая электронная доска (whiteboard).

RTC поддерживает информацию о присутствии (presence information), на основе которой клиенты могут связываться с контактами через сервер-регистратор (registrar server), хранящий информацию о текущих адресах контактов. Адресом контакта может быть ПК или телефон, а в будущем и мобильный телефон, пейджер или другое карманное устройство. Например, если приложение пытается связаться с контактом по его рабочему адресу и информация о присутствии указывает на то, что данный контакт доступен через домашний ПК, RTC автоматически перенаправит соединение на этот адрес. RTC API также обеспечивает невмешательство в частную жизнь, позволяя блокировать определенные вызовы.

DCOM

Microsoft COM API позволяет составлять приложения из компонентов, и каждый компонент представляет собой заменяемый самодостаточный модуль. Любой СОМ-объект экспортирует объектно-ориентированный интерфейс для манипулирования своими данными. Поскольку СОМ-объекты предоставляют четко определенные интерфейсы, разработчики могут реализовать новые объекты для расширения существующих интерфейсов и динамического добавления новой функциональности в приложения.

DCOM — это расширение СОМ, которое дает возможность размещать компоненты приложения на разных компьютерах, при этом приложению безразлично, что один СОМ-объект находится на локальном компьютере, а другой — на каком-то компьютере в локальной сети. Таким образом, DCOM упрощает разработку распределенных приложений. DCOM не является автономным API — в своей работе он опирается на RPC.

Message Queuing

Message Queuing представляет собой универсальную платформу для разработки распределенных приложений, использующих преимущества свободно связанного обмена сообщениями (loosely coupled messaging). Поэтому Message Queuing является также API-интерфейсом и инфраструктурой передачи сообщений. Гибкость Message Queuing определяется тем, что его очереди служат репозитариями сообщений, в которые отправители помещают сообщения для посылки получателям и из которых получатели извлекают адресованные им сообщения. Отправителям и получателям не требуется ни устанавливать соединения, ни работать в одно и то же время. A это позволяет асинхронно обмениваться сообщениями, не устанавливая прямых соединений.

Примечательная особенность Message Queuing — его интеграция с MTS (Microsoft Transaction Server) и SQL Server, что дает возможность Message Queuing участвовать в транзакциях, координируемых MS DTC (Microsoft Distributed Transaction Coordinator). Используя MS DTC c Message Queuing, можно разрабатывать для трехуровневых приложений надежные компоненты, отвечающие за обработку транзакций.

UPnP

Universal Plug and Play (UPnP) — это распределенная, открытая сетевая архитектура для поддержки соединений с интеллектуальными устройствами и точками управления (control points), подключенными к домашним сетям, интрасетям или напрямую к Интернету. Она построена на принятых стандартах и опирается на существующие технологии TCP/IP и Web. UPnP не требует конфигурирования и поддерживает автоматическое распознавание широкого спектра устройств. Она позволяет устройству динамически подключаться к сети, получать IP-адрес и сообщать о своих возможностях, когда поступает соответствующий запрос. Точки управления могут применять Control Point API в сочетании с технологией UPnP для определения присутствия и возможностей остальных устройств в сети. Устройство может автоматически выходить из сети, если оно больше не используется.

Поддержка нескольких редиректоров

У приложений есть два способа просмотра удаленных ресурсов или доступа к ним. Один из них заключается в использовании стандарта UNC и прямой адресации к удаленным ресурсам через Windows-функции, а второй — в применении Windows Networking (WNet) API для перечисления компьютеров и экспортируемых ими ресурсов. Оба подхода опираются на возможности редиректора. Для доступа клиентов к CIFS-серверам Microsoft поставляет редиректор CIFS, у которого есть компонент режима ядра (FSD редиректора) и компонент пользовательского режима (служба рабочей станции). Microsoft также предоставляет редиректор, способный обращаться к ресурсам серверов Novell NetWare, а сторонние разработчики могут добавлять в

Windows собственные редиректоры. B этом разделе мы расскажем о программном обеспечении, которое решает, какой редиректор следует вызвать для обработки запроса на удаленный ввод-вывод. За это отвечают следующие компоненты.

• Маршрутизатор многосетевого доступа (multiple provider router, MPR) Это DLL (\Windows\System32\Mpr.dll), определяющая, к какой сети следует обратиться, когда приложение использует Windows WNet API для просмотра удаленной файловой системы.

• Многосетевой UNC-провайдер (multiple UNC provider, MUP) Драйвер (\Windows\System32\Drivers\Mup.sys), определяющий, к какой сети следует обратиться, когда приложение использует Windows API ввода-вывода для открытия удаленных файлов.

Маршрутизатор многосетевого доступа

Windows-функции WNet позволяют приложениям (включая Windows Explorer и My Network Places) подключаться к сетевым ресурсам (файлам и принтерам), а также просматривать содержимое удаленных файловых систем любого типа. Так как этот API предназначен для работы с различными сетями и по разным протоколам, необходимо специальное программное обеспечение, способное посылать запросы по сети и правильно интерпретировать результаты, получаемые от удаленных серверов. Это программное обеспечение показано на рис. 13–13.

Провайдер (provider) — это программный компонент, позволяющий Windows выступать в качестве клиента какого-либо удаленного сервера. B число операций, выполняемых провайдером WNet, входят установление и разрыв сетевых соединений, удаленная печать и передача данных. Встроенный провайдер WNet включает DLL, службу рабочей станции и редиректор. Поставщики других сетей должны предоставлять только DLL и редиректор.

Когда приложение вызывает некую функцию WNet, этот вызов передается непосредственно MPR DLL. MPR принимает вызов и определяет, какой из провайдеров WNet распознает запрошенный ресурс. Все DLL провайдеров, расположенные ниже MPR, предоставляют набор стандартных функций, в совокупности называемых интерфейсом сетевого доступа (network provider interface). Этот интерфейс позволяет MPR определить, к какой сети пытается обратиться приложение, и направить вызов соответствующему провайдеру WNet. Провайдером службы рабочей станции является \Windows\System32\Ntlanman.dll, что указывается в параметре ProviderPath в разделе реестра HKLM\SYSTEM\CurrentControlSet\Services\LanManWorkstation\NetworkProvider.

Рис. 13–14. Редактор порядка провайдеров (служб доступа к сети)

Когда MPR вызывается для подключения к удаленному сетевому ресурсу API-функцией WNetAddConnection, он просматривает в реестре параметр HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\HwOrder\ProviderOrder, чтобы определить, какие провайдеры сетей загружены. Далее он опрашивает их в том порядке, в каком они перечислены в реестре, и делает это до тех пор, пока один из них не распознает сетевой ресурс или пока все они не будут опрошены. Параметр ProviderOrder можно изменить через диалоговое окно Advanced Settings (Дополнительные параметры), показанное на рис. 13–14. (B системе, в которой был сделан этот экранный снимок, установлен только один провайдер.) B Windows 2000 или при настройке меню Start (Пуск) в традиционном стиле это диалоговое окно вызывается из меню Advanced (Дополнительно) апплета Network Connections (Сетевые подключения), который запускается несколькими способами. Вы можете, например, щелкнуть правой кнопкой мыши значок My Network Places (Мое сетевое окружение) на рабочем столе и выбрать из контекстного меню команду Properties (Свойства), либо открыть меню Start (Пуск), затем подменю Settings (Настройка) и выбрать команду Network Connections (Сетевые подключения).

Функция WNetAddConnection может также назначить удаленному ресурсу букву диска или имя устройства. B этом случае она направляет вызов соответствующему компоненту сетевого доступа. Тот в свою очередь создает объект «символьная ссылка» в пространстве имен диспетчера объектов, и этот объект увязывает данную букву диска с редиректором нужной сети (т. е. с удаленным FSD).

Ha рис. 13–15 показан каталог \?? в системе Windows 2000, в котором вы заметите несколько букв диска, представляющих соединения с удаленными файловыми ресурсами. Как видите, редиректор создает объект «устройство» с именем \Device\LanmanRedirector, а дополнительный текст, который входит в значение символьной ссылки, сообщает редиректору, какому удаленному ресурсу соответствует буква диска. Когда пользователь открывает X: \ Book\Chapl3.doc, редиректору передается неразобранная часть пути, которая разрешается через символьную ссылку как «;X:0\dual\e\Book\ Chapl3doc». Редиректор отмечает, что данный ресурс расположен на общем диске E сервера dual

Как и встроенный редиректор, другие редиректоры тоже создают объект «устройство» в пространстве имен диспетчера объектов в процессе своей загрузки и инициализации. После этого, когда WNet или другой API обращается к диспетчеру объектов для открытия ресурса, расположенного в другой сети, диспетчер использует данный объект «устройство» как точку входа в удаленную файловую систему Он вызывает метод разбора, принадлежащий диспетчеру ввода-вывода и сопоставленный с объектом, для поиска FSD редиректора, способного обработать данный запрос (о драйверах файловых систем см. главу 12).

Многосетевой UNC-провайдер

Многосетевой UNC-провайдер (Multiple UNC Provider, MUP) — сетевой компонент, сходный с MPR. Он обрабатывает запросы ввода-вывода (адресованные к файлам или устройствам) с UNC-именами (именами, которые начинаются с символов \\, указывающих, что данный ресурс находится в сети). MUP, как и MPR, определяет; какой локальный редиректор распознает удаленный ресурс. Ho MUP в отличие от MPR является драйвером устройства (загружаемым при загрузке системы), который выдает запросы на ввод-вывод драйверам более низкого уровня, в данном случае — редиректорам, как показано на рис. 13–16. Mup.sys также содержит клиентскую реализацию Distributed File System (DFS). Клиент DFS включен по умолчанию, и его можно отключить, присвоив DWORD-параметру реестра HKLM\System\CurrentCont-rolSet\Services\Mup\DisableDfs значение 1.

При загрузке MUP создает объект «устройство» с именем \Device\Mup. Когда сетевой редиректор вроде CIFS загружает редиректор, тот создает именованный объект «устройство» (скажем, \Device\LanmanRedirector) и регистрируется в MUP как UNC-провайдер вызовом функции FsRtlRegister.

UncProvider. Если этот редиректор — первый из зарегистрированных и если поддержка DFS-клиента в MUP отключена, то FsRtlRegisterUncProvider создает символьную ссылку \??\UNC, которая указывает на объект «устройство» редиректора; в ином случае MUP настраивает символьную ссылку \Global??\ UNC (\??\UNC в Windows 2000) так, чтобы она указывала на его объект «устройство», \Device\MUP

Драйвер MUP активизируется, когда приложение впервые пытается открыть удаленный файл или устройство по UNC-имени (а не по букве сетевого диска). Получив запрос на ввод-вывод с UNC-путем, Kernel32.dll (экспортирующая API-функции файлового ввода-вывода) на клиентской стороне добавляет переданный в запросе UNC-путь к строке \Global??\UNC после чего вызывает системный сервис NtCreateFile для открытия файла.

Если зарегистрирован только один провайдер сети, то \Global??\UNC разрешается в объект «устройство», представляющий драйвер, и запрос обрабатывается этим драйвером. При наличии нескольких зарегистрированных провайдеров \Global??\UNC разрешается в \Device\MUP, и MUP должен определить, какой провайдер будет обрабатывать данный запрос.

Когда драйвер MUP принимает запрос ввода-вывода и клиент DFS включен, MUP сначала определяет, соответствует ли указанный путь DFS-пути (DFS-пути тоже форматируются по стандарту UNC), и, если да, сам обрабатывает запрос. Если клиент DFS отключен или путь не соответствует DFS-пути, MUP считывает параметр реестра HKLM\SYSTEM\CurrentControlSet\ Control\NetworkProvider\Order\ProviderOrder, чтобы определить приоритет провайдеров сетей, зарегистрированных через FsRtlRegisterUncProvider. Затем MUP поочередно опрашивает провайдеры в том порядке, в каком они перечислены в данном параметре реестра, до тех пор, пока один из них не сообщит, что он распознал данный путь, или пока не будут опрошены все имеющиеся провайдеры. MUP игнорирует те редиректоры, которые указаны в параметре ProviderOrder, но не зарегистрированы. Когда один из редиректоров распознает путь, он сообщает, какая часть пути уникальна именно для него. Например, если путем является строка «\\WIN2K3SERVER\PUBLIC\Win-dowsinternals\Chapl3.doc», редиректор может распознать и объявить своей подстроку «\\WIN2K3SERVER\PUBLIC». Драйвер MUP кэширует эту информацию и впоследствии пересылает запросы, начинающиеся с данной подстроки, непосредственно этому редиректору, пропуская стадию опроса. Кэш драйвера MUP хранит данные в течение определенного периода, поэтому через некоторое время сопоставление подстроки с данным редиректором становится недействительным.

Разрешение имен

Разрешение имен (name resolution) — это процесс, в ходе которого символьное имя вроде Mycomputer или www.microsoft.com транслируется в числовой адрес типа 192.l68.1.1, распознаваемый стеком протоколов. B этом разделе описываются два TCP/IP-протокола разрешения имен, предоставляемые Windows, — DNS (Domain Name System) и WINS (Windows Internet Name Service).

DNS

DNS (Domain Name System) — стандарт трансляции имен в Интернете (например, www.microsoft.com) в соответствующие IP-адреса. Сетевое приложение, которому требуется разрешить DNS-имя в IP-адрес, использует TCP/IP для передачи серверу запроса на поиск DNS-имени. DNS-серверы реализуют распределенную базу данных сопоставлений имен и IP-адресов, используемых при разрешении. Каждый сервер обслуживает разрешение имен для определенной зоны. Подробное описание DNS не входит в задачи этой книги, но DNS представляет собой основной протокол разрешения имен в Windows.

DNS-сервер реализован в виде Windows-сервиса (\Windows\System32\ Dns.exe), который входит в состав серверных версий Windows. DNS-сервер в стандартной реализации использует в качестве базы данных текстовый файл, но DNS-сервер в Windows может быть сконфигурирован на хранение зонной информации в Active Directory.

WlNS

Сетевая служба WINS (Windows Internet Name Service) хранит и поддерживает сопоставления между NetBIOS-именами и IP-адресами, используемые TCP/IP-приложениями на основе NetBIOS. Если WINS не установлена, NetBIOS разрешает имена, рассылая широковещательные сообщения в локальной подсети. Заметьте, что NetBIOS-имена вторичны по отношению к DNS-именам в случае приложений Windows Sockets: имена компьютеров регистрируются и разрешаются сначала через DNS. Windows возвращается к NetBIOS-именам, только если разрешение имени через DNS заканчивается неудачно.

Драйверы протоколов

Драйверы сетевых API должны принимать запросы, адресованные к API, и транслировать их в низкоуровневые запросы сетевых протоколов для передачи по сети. Драйверы API выполняют реальную трансляцию с помощью драйверов транспортных протоколов в режиме ядра. Отделение API от нижележащих протоколов придает сетевой архитектуре гибкость, позволяющую каждому API использовать множество различных протоколов. B Windows входят следующие драйверы протоколов: TCP/IP, TCP/IP с IPv6, NWLink и Apple-Talk. Ниже дается краткое описание каждого из этих протоколов.

• Взрывное развитие Интернета и популярность TCP/IP обусловили статус этих протоколов как основных в Windows. TCP/IP был разработан DARPA (Defense Advanced Research Projects Agency) в 1969 году как фундамент Интернета, поэтому характеристики TCP/IP (поддержка маршрутизации и хорошая производительность в WAN) благоприятствуют его использованию в глобальных сетях. TCP/IP — основной стек протоколов в Windows. Он устанавливается по умолчанию, и его нельзя удалить.

• 4-байтовые сетевые адреса, используемые протоколом IPv4 в стандартном стеке протоколов TCP/IP, ограничивают число общедоступных IР-адресов примерно до 4 миллиардов. И это становится серьезной проблемой, поскольку в Интернете появляется все больше и больше устройств, таких как сотовые телефоны и КПК. По этой причине начинается внедрение протокола IPv6, в котором каждый адрес имеет 16 байтов. B Windows XP (Service Pack 1 и выше) и Windows Server 2003 включен стек TCP/IP, \Win-dows\System32\Drivers\Tcpip6.sys, реализующий IPv6. Windows-реализация IPv6 совместима с сетями на основе IPv4 за счет туннелирования.

• NWLink состоит из протоколов Novell IPX и SPX. NWLink включен в Windows для взаимодействия с серверами Novell NetWare.

• Протокол AppleTalk используется в сетях Apple Macintosh; его поддержка позволяет Windows взаимодействовать со службами доступа к файлам и принтерам в сетях на основе AppleTalk.

B Windows транспорты TDI в общем случае реализуют все протоколы, сопоставленные с основным стеком протоколов. Например, драйвер TCP/IP IPv4 (\Windows\System32\Drivers\Tcpip.sys) реализует протоколы TCP, UDP, IP, ARP, ICMP и IGMP Для представления конкретных протоколов транспорт TDI обычно создает объекты «устройство», что позволяет клиентам получать объект «файл», представляющий нужный протокол, и выдавать ему запросы на сетевой ввод-вывод с использованием IRP Драйвер TCP/IP создает несколько объектов «устройство» для представления различных протоколов, доступных клиентам TDI: \Device\Tcp, \Device\Udp и \Device\Ip, а также (в Windows XP и Windows Server 2003) \Device\Rawip и \Device\Ipmulticast.

ЭКСПЕРИМЕНТ: просмотр объектов «устройство», принадлежащих TCP/IP

C помощью отладчика ядра можно изучить эти объекты в работающей системе. Команда !drvobj позволяет узнать адрес каждого объекта «устройство» драйвера, a !devobj — просмотреть имя и другие сведения о конкретном объекте.

Microsoft определила стандарт TDI (Transport Driver Interface), чтобы драйверам сетевых API не приходилось использовать отдельные интерфейсы для каждого необходимого им транспортного протокола. Как уже говорилось, интерфейс TDI фактически представляет собой правила форматирования сетевых запросов в IRP, а также выделения сетевых адресов и коммуникационных соединений. Транспортные протоколы, отвечающие стандарту TDI, экспортируют интерфейс TDI своим клиентам, в число которых входят драйверы сетевых API, например AFD и редиректор. Транспортный протокол, реализованный в виде драйвера устройства Windows, называется транспортом TDI. Поскольку транспорты TDI являются драйверами устройств, они преобразуют получаемые от клиентов запросы в формат IRP.

Интерфейс TDI образуют функции поддержки из библиотеки \Windows\ System32\Drivers\Tdi.sys вместе с определениями, включаемыми разработчиками в свои драйверы. Модель программирования TDI очень напоминает таковую в Winsock. Устанавливая соединение с удаленным сервером, клиент TDI выполняет следующие действия.

1. Чтобы выделить адрес, клиент создает и форматирует TDI IRP-пакет address open. Транспорт TDI возвращает объект «файл», который представляет адрес и называется объектом адреса (address object). Эта операция эквивалентна вызову Winsock-функции bind.

2. Далее клиент создает и форматирует TDI IRP-пакет connection open, a транспорт TDI возвращает объект «файл», который представляет соединение и называется объектом соединения (connection object). Эта операция эквивалентна вызову Winsock-функции socket.

3. Клиент сопоставляет объект соединения с объектом адреса с помощью TDI IRP-пакета associate address (для этой операции эквивалентных функций Winsock нет).

4. Клиент TDI, соглашающийся установить удаленное соединение, выдает TDI IRP-пакет listen, указывая для объекта соединения максимальное число подключений. После этого он выдает TDI IRP-пакет accept, обработка которого заканчивается либо установлением соединения с удаленной системой, либо ошибкой. Эти операции эквивалентны вызову Winsock-функций listen и accept.

5. Клиент TDI, которому нужно установить соединение с удаленным сервером, выдает TDI IRP-пакет connect, указывая объект соединения, выполняемый транспортом TDI после установления соединения или появления ошибки. Выдача TDI IRP-пакета connect эквивалентна вызову Winsock-функции connect.

TDI также поддерживает коммуникационную связь, не требующую логических соединений, для протоколов соответствующего типа, например для UDP. Кроме того, TDI предоставляет клиенту TDI средства для регистрации в транспортах TDI своих функций обратного вызова по событиям (event callbacks) (т. е. функций, вызываемых напрямую). Например, при получении данных через сеть транспорт TDI может вызвать зарегистрированную клиентом функцию обратного вызова для приема данных. Поддержка функций обратного вызова на основе событий позволяет транспорту TDI уведомлять своих клиентов о сетевых событиях, а клиенты, использующие такие функции, могут не выделять ресурсы для приема данных из сети, поскольку им доступно содержимое буферов, предоставляемых драйвером протокола TDL.

ЭКСПЕРИМЕНТ: наблюдаем активность, связанную с TDI

Утилита TDImon (wwwsysinternats.com) является разновидностью драйвера фильтра, который подключается к объектам «устройство» \Device\Tcp и \Device\Udp, создаваемым драйвером TCP/IP. После подключения TDImon может наблюдать за каждым IRP, выдаваемым клиентами TDI своим протоколам. TDImon также может отслеживать функ ции обратного вызова по событиям, перехватывая запросы на их регистрацию от клиентов TDI Драйвер TDImon посылает информацию об активности TDI своему графическому пользовательскому интерфейсу, который и отображает эти сведения (время операции, тип активности TDI, локальный и удаленный адреса TCP-соединения или локальный адрес конечной точки UDP, код статуса IRP и др.). Ниже приведен экранный снимок окна TDImon, в котором ведется мониторинг активности TDI при просмотре Web-страницы в Internet Explorer.

Как доказательство «врожденной» асинхронности операций TDI, в колонке Result выводятся сообщения «PENDING». Это говорит о том, что операция инициирована, но обработка IRP, вызвавшего ее выполнение, еще не завершена. Чтобы было видно, в каком порядке одни операции завершаются относительно начала других, факт выдачи каждого IRP или обращения к функции обратного вызова отмечается своим порядковым номером. Если до завершения обработки данного IRP генерируются или завершаются другие IRP, эти факты также отмечаются соответствующими порядковыми номерами, которые показываются в колонке Result. Например, на нашей иллюстрации IRP 1278 завершился после генерации IRP 1279, поэтому в колонке Result для IRP 1278 выводится число 1280.

Расширения TCP/IP

Ряд сетевых сервисов Windows расширяет базовые сетевые возможности драйвера TCP/IP за счет применения драйверов-надстроек, интегрируемых с драйвером TCP/IP через закрытые интерфейсы. K числу таких сервисов относятся трансляция сетевых адресов (NAT), IP-фильтрация, подключение IP-ловушек (IP-hooking) и IP-безопасность (IPSec). Ha рис. 13–17 показано, как эти расширения связаны с драйвером TCP/IP.

Трансляция сетевых адресов

Трансляция сетевых адресов (network address translation, NAT) представляет собой сервис маршрутизации, позволяющий отображать несколько закрытых IP-адресов на один общий IP-адрес, видимый в Интернете. Без NAT для коммуникационной связи с Интернетом каждому компьютеру в локальной сети (LAN) пришлось бы назначать свой IP-адрес, видимый в Интернете. NAT дает возможность назначить такой IP-адрес только одному из компьютеров в локальной сети и подключать остальные компьютеры к Интернету через него. NAT по мере необходимости транслирует LAN-адреса в общий IР-адрес, перенаправляя пакеты из Интернета на соответствующий компьютер в локальной сети.

Компоненты NAT в Windows — драйвер устройства NAT (\Windows\System32\Drivers\Ipnat.sys), взаимодействующий со стеком TCP/IP, а также редакторы, с помощью которых возможна дополнительная обработка пакетов (помимо трансляции адресов и портов). NAT может быть установлен как маршрутизирующий протокол через оснастку Routing And Remote Access (Маршрутизация и удаленный доступ) консоли MMC или настройкой Интернет-соединения на общее использование через апплет Network Connections (Сетевые подключения). (Более широкие возможности в настройке NAT предоставляет оснастка Routing And Remote Access.)

IP-фильтрация

B Windows 2000, Windows XP и Windows Server 2003 есть минимальные базовые средства IP-фильтрации, позволяющие пропускать пакеты только по определенным портам или IP-протоколам. Хотя эти средства в какой-то мере защищают компьютер от несанкционированного доступа из сети, их недостаток в том, что они статичны и не предусматривают возможность автоматического создания новых фильтров для трафика, инициируемого работающими на компьютере приложениями.

B Windows XP введен персональный брандмауэр — Windows Firewall, возможности которого шире, чем у базовых средств фильтрации. Windows Firewall реализует брандмауэр с поддержкой состояний (stateful firewall), который отслеживает и различает трафик, генерируемый TCP/IP, и трафик, поступающий из LAN и Интернета. Когда вы включаете Windows Firewall для какого-либо сетевого интерфейса, весь незатребованный входящий трафик по умолчанию отбрасывается. Приложение или пользователь может определить исключения, чтобы сервисы, работающие на данном компьютере (вроде службы доступа к общим файлам и принтерам), были доступны с других компьютеров.

Сервис Windows Firewall/ICS (Internet Connection Sharing), выполняемый в процессе Svchost, передает правила исключения, определенные через пользовательский интерфейс Windows Firewall, драйверу IPNat. B режиме ядра Windows Firewall реализован в том же драйвере (\Windows\System32\Drivers\Ipnat.Sys), который реализует трансляцию сетевых адресов (NAT). Драйвер NAT регистрируется в драйвере TCP/IP как драйвер ловушки брандмауэра (firewall hook). Драйвер TCP/IP выполняет функции обратного вызова каждой зарегистрированной ловушки брандмауэра в ходе обработки входящих и исходящих IP-пакетов. Функция обратного вызова может выступать в роли NAT, модифицируя адреса источника и получателя в пакете, или в роли брандмауэра, возвращая код состояния, указывающий TCP/IP отбросить пакет.

Хотя Ipnat реализует Windows Firewall с применением интерфейса ловушек брандмауэра TCP/IP, Microsoft рекомендует сторонним разработчикам реализовать поддержку фильтрации пакетов в виде промежуточного драйвера NDIS (о нем мы еще расскажем в этой главе).

IP-фильтр и ловушка фильтра

B Windows XP и Windows Server 2003 включен API фильтрации пакетов пользовательского режима, а также драйвер фильтра IP, \Windows\System32\ Drivers\Ipfltrdrv.sys, которые позволяют приложениям управлять входящими и исходящими пакетами. Кроме того, драйвер фильтра IP дает возможность максимум одному драйверу регистрироваться в качестве драйвера ловушки фильтра (filter hook). TCP/IP — по аналогии с тем, как он взаимодействует с драйверами ловушек брандмауэра, — выполняет функцию, которую указывает драйвер фильтра IP, а это позволяет IP-фильтру отбрасывать или модифицировать пакеты. B свою очередь IP-фильтр обращается к функции обратного вызова, заданной драйвером ловушки фильтра, и тем самым передает изменения или запрос на отклонение пакета драйверу TCP/IP.

Функциональность ловушки фильтра, предоставляемая системой, дает возможность сторонним разработчикам добавлять новые средства трансляции, брандмауэра, протоколирования и т. д.

IP-безопасность

IP-безопасность (Internet Protocol Security, IPSec) интегрирована со стеком TCP/IP и защищает одноадресные (unicast) IP-данные от перехвата и несанкционированной модификации, подмены IP-адресов и атак через посредника (man-in-the-middle attacks). IPSec обеспечивает глубоко эшелонированную оборону от сетевых атак с недоверяемых компьютеров, от атак, которые могут привести к отказу в обслуживании, от повреждения данных, кражи информации и учетных данных пользователей, а также от попыток захватить административный контроль над серверами, другими компьютерами и сетью. Эти цели реализуются за счет сервисов защиты на основе шифрования, протоколов безопасности и динамического управления ключами. При обмене одноадресными IP-пакетами между доверяемыми хостами IPSec поддерживает следующую функциональность:

• аутентификацию источника данных — проверку источника IP-пакета и запрет несанкционированного доступа к данным;

• целостность данных — защиту IP-пакета от модификации в процессе доставки и распознавание любых изменений;

• конфиденциальность — содержимое IP-пакетов зашифровывается перед отправкой, благодаря чему их содержимое может быть расшифровано только указанным адресатом;

• защиту от повторений пакетов (anti-replay, или replay protection) — гарантирует уникальность каждого IP-пакета и невозможность его повторного использования. Злоумышленник, даже если он сумеет перехватить IP-пакеты, не сможет повторно использовать их для установления сеанса связи или неавторизованного доступа к информации. Для защиты от сетевых атак вы можете настроить IPSec на фильтрацию пакетов хостом (host-based packet filtering) и разрешать соединения только с доверяемыми компьютерами. После настройки на фильтрацию пакетов хостом IPSec может разрешать или блокировать определенные виды одноадресного IP-трафика, исходя из адресов источника и получателя, заданных протоколов и портов. Поскольку IPSec интегрирован с IP-уровнем (уровнем 3) стека TCP/IP и действует на все приложения, вам не понадобится настраивать параметры безопасности индивидуально для каждого приложения, работающего с TCP/IP.

B среде Active Directory групповая политика позволяет настраивать домены, сайты и организационные единицы (organizational units, OU), а политики IPSec можно закреплять за нужными объектами групповой политики (Group Policy Objects, GPO). B качестве альтернативы можно конфигурировать и применять локальные политики IPSec. Политики IPSec хранятся в Active Directory, а копия параметров текущей политики поддерживается в кэше в локальном реестре. Локальные политики IPSec хранятся в реестре локальной системы.

Для установления доверяемого соединения IPSec использует взаимную аутентификацию (mutual authentication), при этом поддерживаются следующие методы аутентификации: Kerberos версии 5, сертификат открытого ключа X.509 версии 3 или на основе общего ключа (preshared key).

Windows-реализация IPSec основана на RFC, относящихся к IPSec. Архитектура Windows IPSec включает IPSec Policy Agent (Агент политики IP-безопасности), протокол Internet Key Exchange (IKE) и драйвер IPSec.

• Агент политики IP-безопасности Выполняется как сервис в процессе LSASS (о LSASS см. главу 8). B ММС-оснастке Services (Службы) в списке служб он отображается как IPSEC Services (Службы IPSEC). Агент политики IP-безопасности получает политику IPSec из домена Active Directory или из локального реестра и передает фильтры IP-адресов драйверу IPSec, а параметры аутентификации и безопасности — IKE.

• IKE Ожидает от драйвера IPSec запросы на согласование сопоставлений безопасности (security associations, SA), согласовывает SA, а потом возвращает параметры SA драйверу IPSec. SA — это набор взаимно согласованных параметров политики IPSec и ключей, определяющий службы и механизмы защиты, которые будут использоваться при защищенной коммуникационной связи между двумя равноправными хостами с IPSec. Каждое SA является односторонним, или симплексным, соединением, которое защищает передаваемый по нему трафик. IKE согласует SA основного и быстрого режимов, когда от драйвера IPSec поступает соответствующий запрос. SA основного режима IKE (или ISAKMP) защищает процесс согласования, выполняемый IKE, a SA быстрого режима (или IPSec) — трафик приложений.

• Драйвер IPSec Это драйвер устройства (\Windows\System32\Drivers\ Ipsec.sys), который привязывается к драйверу TCP/IP и который обрабатывает пакеты, передаваемые через драйвер TCP/IP. Драйвер IPSec отслеживает и защищает исходящий одноадресный IP-трафик, а также отслеживает, расшифровывает и проверяет входящие одноадресные 1Р-пакеты. Этот драйвер принимает фильтры от агента политики 1Р-безопасности, а затем пропускает, блокирует или защищает пакеты в соответствии с критериями фильтров. Для защиты трафика драйвер IPSec использует параметры активного SA либо запрашивает создание новых SA. ММС-оснастка IP Security Policy Management (Управление политикой безопасности IP) позволяет создавать политику IPSec и управлять ею. C помощью этой оснастки можно создавать, изменять и сохранять локальные политики IPSec или политики IPSec на основе Active Directory, а также модифицировать политику IPSec на удаленных компьютерах. B Windows XP и Windows Server 2003, после того как защищенное IPSec-соединение установлено, вы можете отслеживать информацию IPSec для локального и удаленных компьютеров через ММС-оснастку IP Security Monitor (Монитор IP-безопасности).

Драйверы NDIS

Когда драйверу протокола требуется получить или отправить сообщение в формате своего протокола, он должен сделать это с помощью сетевого адаптера. Поскольку ожидать от драйверов протоколов понимания нюансов работы каждого сетевого адаптера нереально (на рынке предлагается несколько тысяч моделей сетевых адаптеров с закрытой спецификацией), производители сетевых адаптеров предоставляют драйверы устройств, которые принимают сетевые сообщения и передают их через свои устройства. B 1989 году компании Microsoft и 3Com совместно разработали спецификацию Network Driver Interface Specification (NDIS), которая определяет аппаратно-независимое взаимодействие драйверов протоколов с драйверами сетевых адаптеров. Драйверы сетевых адаптеров, соответствующие NDIS, называются драйверами NDIS или минипорт-драйверами NDIS. C Windows 2000 поставляется NDIS версии 5, а с Windows XP и Windows Server 2003 — версии 5.1.

Библиотека NDIS (\Windows\System32\Drivers\Ndis.sys) реализует пограничный уровень между транспортами TDI (в типичном случае) и драйверами NDIS. Как и Tdi.sys, библиотека NDIS является вспомогательной и используется клиентами драйверов NDIS для форматирования команд, посылаемых этим драйверам. Драйверы NDIS взаимодействуют с библиотекой, чтобы получать запросы и отвечать на них. Взаимосвязи между компонентами, имеющими отношение к NDIS, показаны на рис. 13–18.

Одна из целей Microsoft при разработке сетевой архитектуры состояла в том, чтобы производителям сетевых адаптеров было легче разрабатывать драйверы NDIS и переносить их код между потребительскими версиями Windows и Windows 2000. Таким образом, библиотека NDIS предоставляет драйверам не просто вспомогательные пограничные процедуры NDIS, а целую среду выполнения драйверов NDIS. Последние не являются истинными драйверами Windows, поскольку не могут функционировать без инкапсулирующей их библиотеки NDIS. Этот инкапсулирующий уровень является настолько плотной оболочкой драйверов NDIS, что они не принимают и не обрабатывают IRR Вместо этого драйверы протоколов TDI вызывают функцию NdisAllocatePacket в библиотеке NDIS и передают пакеты минипорту NDIS, вызывая соответствующую NDIS-функцию, например NdisSend. По умолчанию драйверам NDIS также не приходится заботиться о реентерабельности, когда библиотека NDIS вызывает драйвер с новым запросом до того, как он успел обработать предыдущий запрос. Освобождение от поддержки реентерабельности кода означает, что создатели драйверов NDIS могут не думать о сложных проблемах синхронизации, которые еще больше усложняются в многопроцессорных системах.

ПРИМЕЧАНИЕ Библиотека NDIS использует для представления запросов ввода-вывода NDIS-пакеты, а не IRR Транспорты TDI создают NDIS-пакет вызовом NdisAllocatePacket, после чего пакет передается минипорту NDIS вызовом одной из функций библиотеки NDIS (например, NdisSend).

Хотя сериализация обращений к драйверам NDIS, осуществляемая библиотекой NDIS, упрощает разработку, она может помешать масштабированию многопроцессорных систем. Некоторые операции стандартных драйверов NDIS 4 (версия библиотеки NDIS 4 из Windows NT 4) плохо масштабируются в многопроцессорных системах. B NDIS 5 разработчики получили возможность отказаться от такой сериализации. Драйвер NDIS 5 может сообщить библиотеке NDIS, что сериализация ему не нужна, и тогда библиотека NDIS переправляет драйверу запросы по мере получения соответствующих IRP B этом случае ответственность за управление параллельными запросами ложится на драйвер NDIS, но отказ от сериализации окупается повышением производительности в многопроцессорных системах.

NDIS 5 также обеспечивает следующие преимущества.

• Драйверы NDIS могут сообщать, активна ли несущая сетевая среда, что позволяет Windows выводить на панель задач значок, показывающий, подключен ли компьютер к сети. Эта функция также позволяет протоколам и другим приложениям быть в курсе этого состояния и соответствующим образом реагировать. Например, транспорт TCP/IP будет использовать эту информацию, чтобы определять, когда нужно заново оценивать информацию об адресах, получаемую им от DHCP

• Аппаратное ускорение TCP/IP-операций (TCP/IP task offload) позволяет минипорту пользоваться аппаратными функциями сетевого адаптера для выполнения таких операций, как расчет контрольных сумм пакетов и все вычисления, связанные с IP-безопасностью (IPSec). Аппаратное ускорение этих операций средствами сетевого адаптера повышает производительность системы, освобождая центральный процессор от выполнения этих задач.

• Функция Wake-On-LAN дает возможность сетевому адаптеру с соответствующей поддержкой выводить систему Windows из состояния с низким энергопотреблением при каких-либо событиях в сети. Сигнал пробуждения может быть инициирован сетевым адаптером при одном из следующих событий: подключении к несущей среде (например, подключении сетевого кабеля к адаптеру) и приеме специфичных для протокола последовательностей байтов (в случае адаптеров Ethernet — при получении волшебного пакета, т. е. сетевого пакета с 16 копиями Ethernet-адреса адаптера подряд).

• NDIS, ориентированная на логические соединения, позволяет драйверам NDIS управлять несущей средой, требующей логических соединений, например устройствами ATM (Asynchronous Transfer Mode). Интерфейсы, предоставляемые библиотекой NDIS драйверам NDIS для взаимодействия с сетевыми адаптерами, доступны через функции, вызовы которых транслируются непосредственно в вызовы соответствующих HAL функций.

ЭКСПЕРИМЕНТ: перечисление загруженных минипортов NDIS

Библиотека расширения отладчика ядра Ndiskd поддерживает команды !miniports и /miniport, которые позволяют с помощью отладчика ядра перечислять загруженные минипорт-драйверы (минипорты) и получать детальную информацию о каком-либо минипорте по заданному адресу блока минипорта (структуры данных, применяемой Windows для отслеживания минипортов). Ниже приведен пример использования команд !miniports и /miniport для вывода списка всех минипорт-драйверов, а также для исследования специфики минипорта, отвечающего за взаимодействие системы с PCI-адаптером Ethernet (заметьте, что WAN-минипорты работают с соединениями удаленного доступа).

Поле Flags исследуемого минипорта показывает, что он поддерживает несериализованные операции (DESERIALIZED), что несущая среда в данный момент активна (MEDIACONNECTED) и что он является минипортом NDIS 5 (NDIS_5_0). Кроме того, выводится информация, отражающая сопоставления состояний электропитания устройства и системы, а также список ресурсов шины, назначенных адаптеру диспетчером Plug and Play (Подробнее о соответствии состояний электропитания устройств и системы см. раздел «Диспетчер электропитания» главы 9.)

Разновидности минипорт-драйверов NDIS

Модель NDIS также поддерживает гибридные NDIS-драйверы транспорта TDI, называемые промежуточными драйверами NDIS (NDIS intermediate drivers). Они размещаются между транспортами TDI и драйверами NDIS. Драйверу NDIS промежуточный драйвер кажется транспортом TDI, а транспорту TDI — драйвером NDIS. Промежуточные драйверы NDIS видят весь сетевой трафик в системе, поскольку они расположены между драйверами протоколов и сетевыми драйверами. Программное обеспечение, предоставляющее сетевым адаптерам поддержку отказоустойчивости и балансировки нагрузки, например Microsoft Network Load Balancing Provider, основано на использовании промежуточных драйверов NDIS.

NDIS, ориентированная на логические соединения

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

Кроме поддержки минипорт-драйверов для сетевых сред, ориентированных на логические соединения, в NDIS 5 включены определения для драйверов, поддерживающих такие минипорт-драйверы.

• Диспетчеры вызовов (call managers) являются драйверами NDIS, которые предоставляют сервисы настройки и завершения вызовов для клиентов, ориентированных на логические соединения (см. ниже). Диспетчер вызовов использует ориентированный на логические соединения мини-порт, чтобы обмениваться сигнальными сообщениями с другими сетевыми компонентами (аппаратными или программными), например с коммутаторами или другими диспетчерами вызовов. Диспетчер вызовов поддерживает один или несколько сигнальных протоколов вроде ATM User-Network Interface (UNI) 3.1.

• Интегрированный Miniport Call Manager (MCM) представляет собой ми-нипорт-драйвер, ориентированный на логические соединения, который также предоставляет клиентам, требующим логических соединений, сервисы диспетчера вызовов. B сущности, MCM — это минипорт-драйвер NDIS со встроенным диспетчером вызовов.

• Ориентированный на логические соединения клиент использует сервисы настройки и завершения вызовов, предоставляемые диспетчером вызовов или MCM, а также передает и принимает обращения к сервисам минипорт-драйвера NDIS, ориентированного на логические соединения. Такой клиент может предоставлять собственные сервисы протокола более высоким уровням сетевого стека или реализовать уровень эмуляции для взаимодействия с унаследованными протоколами, не требующими логических соединений, и соответствующей несущей средой. Пример уровня эмуляции, реализуемой ориентированным на логические соединения клиентом, — LAN Emulation (LANE), которая скрывает от вышележащих протоколов особенности ориентированной на логические соединения ATM и эмулирует для них несущую среду, не требующую соединений (например, Ethernet).

Взаимосвязи между этими компонентами показаны на рис. 13–19.

ЭКСПЕРИМЕНТ: захват сетевых пакетов с помощью сетевого монитора

Windows Server поставляется с программой Network Monitor (Сетевой монитор), которая позволяет перехватывать пакеты, проходящие через один или несколько минипорт-драйверов NDIS, за счет установки промежуточного драйвера NDIS. Для использования Network Monitor нужно сначала установить Network Monitor Tools (Средства сетевого монитора). Для этого откройте апплет Add/Remove Programs (Установка и удаление программ) в Control Panel (Панель управления) и выберите Add/Remove Windows Components (Добавление и удаление компонентов Windows). Укажите строку Management And Monitoring Tools (Средства управления и наблюдения), щелкните кнопку Details (Состав), установите флажок в строке Network Monitor Tools (Средства сетевого монитора) и щелкните кнопку ОК. После установки Network Monitor (Сетевой монитор) можно запустить, выбрав одноименную команду из меню Administrative Tools (Администрирование).

Network Monitor может спросить, за каким сетевым соединением вы хотите наблюдать. Выбрав нужное соединение, можно начать мониторинг, щелкнув на панели инструментов кнопку Start Capture (Начать запись данных). Выполните несколько операций, генерирующих сетевую активность в отслеживаемом соединении. Увидев, что Network Monitor захватил пакеты, остановите мониторинг, щелкнув кнопку Stop And View Capture (Закончить запись и отобразить данные). B результате Network Monitor покажет захваченные данные.

Ha этой иллюстрации показаны пакеты SMB (CIFS), захваченные Network Monitor при обращении системы к удаленным файлам. Если вы дважды щелкнете какую-нибудь строку, Network Monitor переключится в режим отображения пакетов, в котором показывается содержимое различных заголовков в пакетах.

Network Monitor поддерживает и другие возможности, например захват триггеров и фильтров, что делает его мощным диагностическим инструментом, помогающим выявлять и устранять неполадки в сети.

Remote NDIS

До разработки Remote NDIS производитель, например, сетевого USB-устрой-ства должен был предоставлять драйвер, который создавал интерфейс с NDIS (в качестве минипорт-драйвера) и с WDM-драйвером шины USB рис. 13–20). Если производитель оборудования поддерживал другие шины, скажем, IEEE 1394, он должен был реализовать драйверы, создающие интерфейсы с каждым типом шины.

Рис. 13–20. Минипорт-драйвер NDIS для сетевого USB-устройства

Remote NDIS — спецификация для сетевых устройств на PnP-шинах ввода-вывода, допускающих динамическое подключение устройств, например USB, IEEE 1394 и Infiniband. Эта спецификация вообще избавляет производителя оборудования от необходимости писать минипорт-драйвер NDIS, так как в ней определены сообщения, независимые от конкретной шины, и механизм, с помощью которого сообщения передаются по различным шинам. B Remote NDIS включены сообщения для инициализации и сброса состояния устройства, передачи и приема пакетов, установки и опроса параметров устройства, а также для уведомления о состоянии канала передачи данных.

Архитектура Remote NDIS (рис. 13–21) построена на минипорт-драйвере NDIS от Microsoft, \Windows\System32\Drivers\Rndismp.sys, который транслирует NDIS-команды и передает их драйверу транспорта для шины, к которой подключено устройство. Эта архитектура позволяет использовать один минипорт-драйвер NDIS для всех драйверов Remote NDIS и один драйвер транспорта для каждой поддерживаемой шины.

B настоящее время Remote NDIS для USB-устройств поддерживается в Windows XP и Windows Server 2003; кроме того, соответствующие компоненты можно скачать с сайта Microsoft и установить в Windows 2000. Хотя Remote NDIS для устройств IEEE 1394 полностью определен, он пока не поддерживается в Windows.

Рис. 13–21. Архитектура Remote NDIS для сетевых USB-устройств

QoS

Без специальных мер IP-трафик в сети доставляется по принципу «первым пришел — первым обслужен». Приложения не могут контролировать приоритет своих сообщений, и их данные передаются неравномерно: иногда они получают широкую полосу пропускания и малые задержки, а в остальное время — узкую полосу пропускания и длительные задержки. Хотя такой уровень обслуживания в большинстве ситуаций вполне приемлем, все большее число сетевых приложений требует гарантированных уровней обслуживания, или гарантий качества обслуживания (Quality of Service, QoS). Примерами приложений, требующих хорошей сетевой производительности, могут служить видеоконференции, потоковая передача мультимедийной информации и программное обеспечение для планирования ресурсов предприятия (enterprise resource planning, ERP). QoS позволяет приложениям указывать минимальную ширину полосы пропускания и максимальные задержки, которые могут быть удовлетворены только в том случае, если все сетевое программно-аппаратное обеспечение на пути между отправителем и получателем поддерживает стандарты QoS, например IEEE 802.1p — промышленный стандарт, который определяет формат пакетов QoS и реакцию на их получение устройств второго сетевого уровня (коммутаторов и сетевых адаптеров).

Поддержка QoS в Windows основана на наборе Winsock-функций, определенных Microsoft и позволяющих приложениям запрашивать QoS для трафика через свои сокеты Winsock, а также на API управления трафиком (TC API), который позволяет административным приложениям более точно контролировать трафик через сети.

Центральное место в реализации QoS в Windows занимает протокол RSVP (Resource Reservation Setup Protocol), представляющий собой Windows-сервис (\Windows\System32\Rsvp.exe), как показано на рис. 13–22. Провайдер службы RSVP (\Windows\System32\Rsvpsp.dll) передает QoS-запросы приложений через RPC службе RSVP Ta в свою очередь контролирует сетевой трафик с помощью TC API. TC API, реализованный в \Windows\System32\Traffic.dll, посылает команды управления вводом-выводом драйверу GPC (Generic Packet Classifier) (\Windows\System32\Drivers\Msgpc.sys). Дpaйвep GPC — втесном взаимодействии с планировщиком пакетов QoS (промежуточным драйвером NDIS) (\Windows\System32\Drivers\Psched.sys) — контролирует поток пакетов с компьютера в сеть, гарантируя уровни QoS, обещанные конкретным приложениям. При этом он вставляет в пакеты соответствующие заголовки QoS.

ПРИМЕЧАНИЕ B Windows XP и Windows Server 2003 служба RSVP по-прежнему работает, но действует лишь как посредник между приложениями и компонентами, управляющими трафиком.

Привязка

Последний фрагмент головоломки под названием «сетевая архитектура Windows» — способ, посредством которого сетевые компоненты, расположенные на различных уровнях (сетевых API, драйверов транспортов TDI, драйверов NDIS), находят друг друга. Процесс соединения уровней называется привязкой (binding). Вы сами были свидетелем привязки, если хоть раз изменяли конфигурацию сети, добавляя или удаляя компоненты в окне свойств сетевого соединения.

Устанавливая сетевой компонент, вы должны предоставить его INF-файл (INF-файлы описаны в главе 9). Этот файл содержит инструкции, которым должны следовать API-функции установки, чтобы установить и сконфигурировать компонент, учитывая его зависимости от других компонентов. Разработчик может указать зависимости для своего компонента, что позволит SCM загружать его в корректной очередности и только тогда, когда все компоненты, от которых он зависит, уже присутствуют в системе (о SCM см. главу 4). Привязки определяются механизмом привязки (bind engine) на основе информации из INF-файла компонента, что позволяют соединить его с другими компонентами, расположенными на различных уровнях. Эти соединения указывают, какие компоненты нижележащего уровня могут быть использованы сетевым компонентом данного уровня.

Так, служба рабочей станции (редиректор) автоматически привязывается к протоколам TCP/IP и NWLink. Порядок привязки, который можно увидеть на вкладке Adapters And Bindings (Адаптеры и привязки) диалогового OKHaAdvancedSettings (Дополнительные параметры) (рис. 13–23), определяет приоритет привязки. (O том, как открыть это диалоговое окно, см. раздел «Поддержка нескольких редиректоров» ранее в этой главе.) Получив запрос на доступ к удаленному файлу, редиректор выдает запрос обоим драйверам протоколов. После того как редиректору приходит ответ, он дополнительно ждет ответы от любых драйверов протоколов с более высоким приоритетом. И только тогда редиректор возвращает результат вызывающей программе. Поэтому, присвоив высокий приоритет привязкам, которые дают максимальную производительность или применимы к большинству компьютеров в сети, можно добиться определенного выигрыша.

Рис. 13–23. Редактирование привязок в диалоговом окне Advanced Settings

Информация о привязках компонента содержится в параметре Bind подраздела Linkage того раздела реестра, в котором хранится конфигурация данного сетевого компонента. Например, информацию о привязках службы рабочей станции можно найти в HKLM\SYSTEM\CurrentControlSet\Services\ LanmanWorkstation\Linkage\Bind.

Многоуровневые сетевые сервисы

Windows включает сетевые сервисы, построенные на основе API и компонентов, представленных в этой главе. Описание возможностей и внутренних деталей их реализации выходит за рамки этой книги, но мы приведем здесь краткий обзор по удаленному доступу, службе каталогов Active Directory, Network Load Balancing, службе репликации файлов (File Replication Service, FRS) и распределенной файловой системе (Distributed File System, DFS).

Удаленный доступ

Windows Server с установленной службой Routing and Remote Access Service (Служба маршрутизации и удаленного доступа) позволяет клиентам удаленного доступа подключаться к серверам удаленного доступа и обращаться к таким сетевым ресурсам, как файлы, принтеры и службы, создавая иллюзию физического подключения к серверу удаленного доступа через локальную сеть. Windows поддерживает два типа удаленного доступа.

• Удаленный доступ через телефонную линию (dial-up remote access) Используется клиентом при подключении к серверу удаленного доступа через телефонную линию или иную телекоммуникационную инфраструктуру Телекоммуникационная несущая среда используется для создания временного физического или виртуального соединения между клиентом и сервером.

• Удаленный доступ через виртуальную частную сеть (virtual private network, VPN) Позволяет клиентам VPN устанавливать с сервером виртуальное соединение типа «точка-точка» через IP-сеть, например Интернет.

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

Active Directory

Active Directory — реализация службы каталогов LDAP (Lightweight Directory Access Protocol) в Windows. Active Directory основана на базе данных, в которой хранятся объекты, представляющие ресурсы, определенные приложениями в сети Windows. Например, в Active Directory хранится структура и список членов домена Windows, включая информацию об учетных записях и паролях пользователей.

Классы объектов и атрибуты, определяющие свойства объектов, задаются схемой (schema). Иерархическая организация объектов в схеме Active Directory напоминает логическую организацию реестра, где объекты-контейнеры могут хранить другие объекты, включая контейнеры.

Active Directory поддерживает несколько API, используемых клиентами для обращения к объектам в базе данных Active Directory.

• LDAP C API Предназначен для программ на С/С++ и использует сетевой протокол LDAP. Приложения, написанные на С/С++, могут работать с этим API напрямую, а приложения, написанные на других языках, — через транслирующие уровни.

• ADSI (Active Directory Service Interfaces) СОМ-интерфейс Active Directory, реализованный поверх LDAP и абстрагирующий от деталей программирования для LDAP. ADSI поддерживает несколько языков, в том числе Microsoft Visual Basic, C и Microsoft Visual C++. ADSI также доступен приложениям Windows Script Host (Сервер сценариев Windows).

• MAPI (Messaging API) Поддерживается для совместимости с клиентами Microsoft Exchange и клиентскими приложениями Outlook Address Book.

• Security Account Manager (SAM) API Базируется на сервисах Active Directory и предоставляет интерфейс пакетам аутентификации MSVlO (\Windows\System32\Msvl_O.dll) и Kerberos (\Windows\System32\Kdcsvc.dll).

• Сетевые API Windows NT 4 (Net API) Используются клиентами Windows NT 4 для доступа к Active Directory через SAM.

• NTDS API Применяется для просмотра SID и GUID в Active Directory (в основном через DsCrackNames), а также для управления каталогом и его репликацией. Несколько сторонних разработчиков написали приложения, позволяющие вести мониторинг Active Directory через этот API. Active Directory реализована в виде файла базы данных (по умолчанию — в \Windows\Ntds\Ntds.dit), реплицируемой между контроллерами домена. Этой базой данных управляет служба каталогов Active Directory, которая является Windows-сервисом, выполняемым в процессе LSASS; при этом она использует DLL, реализующие структуру базы данных на диске и предоставляющие механизмы обновления на основе транзакций для поддержания целостности базы данных. B Windows 2000 хранилище базы данных Active Directory реализовано на основе ядра Extensible Storage Engine (ESE), применяемого в Microsoft Exchange Server 5.5, a в Windows 2003 Server — на основе ядра ESE, используемого в Microsoft Exchange Server 2000. Архитектура Active Directory показана на рис. 13–24.

Network Load Balancing

Как мы уже говорили в этой главе, в основе компонента Network Load Balancing (Балансировка нагрузки сети), который входит в Windows Advanced Server, лежит технология промежуточных драйверов NDIS. Network Load Balancing допускает создание кластера, включающего до 32 компьютеров, которые в терминологии Network Load Balancing называются узлами кластера (cluster hosts). Кластер поддерживает единый виртуальный 1Р-адрес, публикуемый клиентам, и клиентские запросы поступают ко всем компьютерам кластера. Однако на запрос отвечает только один узел кластера. Драйверы NDIS компонента Network Load Balancing эффективно разделяют клиентское пространство между доступными узлами кластера по аналогии с распределенной обработкой. При таком подходе каждый узел обрабатывает свою порцию клиентских запросов, причем каждый клиентский запрос обрабатывается одним — и только одним — узлом. Если входящий в состав кластера узел определяет, что именно он должен обработать клиентский запрос, то этот узел позволяет запросу пройти до уровня драйвера TCP/IP и в конце концов достичь серверного приложения. Если на узле кластера происходит авария, остальные узлы кластера распознают, что этот узел больше не способен обрабатывать запросы, и перераспределяют поступающие клиентские запросы между собой; при этом клиентские запросы отключенному узлу больше не посылаются. K кластеру можно подключить новый узел на замену потерпевшему аварию, и он автоматически примет участие в обработке клиентских запросов.

Network Load Balancing не является универсальным кластерным решением, поскольку серверные приложения, с которыми взаимодействуют клиенты, должны обладать определенными характеристиками. Во-первых, они должны поддерживать TCP/IP, а во вторых, уметь обрабатывать клиентские запросы на любой системе в кластере Network Load Balancing. Второе требование, как правило, означает, что приложения, у которых для обслуживания клиентских запросов должен быть доступ к общему состоянию (shared state), обязаны сами управлять этим состоянием. B Network Load Balancing не входят сервисы автоматического распределения общего состояния между узлами кластера. Приложения, идеально подходящие для Network Load Balancing, — Web-сервер со статичным информационным наполнением (контентом), Windows Media Server и Terminal Services (Службы терминалов). Пример работы Network Load Balancing показан на рис. 13–25.

Служба репликации файлов

Служба репликации файлов (File Replication Service, FRS) входит в системы Windows Server. Она предназначена в основном для репликации содержимого каталога \SYSVOL контроллера домена (в этом месте контроллеры доменов Windows хранят сценарии регистрации и групповые политики). Кроме того, FRS позволяет реплицировать общие ресурсы DFS (Distributed File System) между системами. FRS поддерживает распределенную репликацию с несколькими хозяевами (distributed multimaster replication), благодаря чему репликацию может проводить любой сервер. Когда реплицируемый файл или каталог изменяется, эти изменения распространяются на другие контроллеры домена.

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

FRS реализована в виде Windows-сервиса (\Windows\System32\Ntfrs.exe), который использует аутентифицируемый RPC для взаимодействия со своими экземплярами, работающими на других компьютерах. Кроме того, поскольку Active Directory располагает собственными средствами репликации, FRS использует API-функции Active Directory для выборки конфигурационной информации из домена Active Directory.

DFS

DFS (Distributed File System) — сервис поверх службы рабочей станции, соединяющий отдельные файловые ресурсы в единое пространство имен. DFS обеспечивает клиентам прозрачный доступ к файловым ресурсам независимо от того, где находятся эти ресурсы — на локальном или удаленных компьютерах. Корнем пространства имен DFS должен быть файловый ресурс, определенный на компьютере с Windows Server.

B дополнение к унифицированному пространству имен сетевых ресурсов DFS дает и другие преимущества при использовании наборов репликации DFS. Администратор может создать набор репликации DFS минимум из двух сетевых ресурсов и использовать механизм репликации вроде FRS для копирования данных между ресурсами, входящими в набор репликации, и тем самым обеспечить синхронизацию их содержимого. DFS поддерживает несколько видов балансировки нагрузки, упорядочивая и/или выбирая сетевые ресурсы, входящие в набор репликации, при обращении клиента к данным из этого набора. DFS также обеспечивает высокую доступность данных, перенаправляя запросы на другие сетевые ресурсы из набора репликации, если какой-то из сетевых ресурсов временно недоступен.

Компоненты, образующие архитектуру DFS, показаны на рис. 13–26. Реализация DFS на серверной стороне включает Windows-сервис (\Windows\ System32\Dfssvc.exe) и драйвер устройства (\Windows\System32\Drivers\ Dfs.sys). Служба DFS отвечает за экспорт интерфейсов управления топологией DFS и поддержку топологии DFS либо в реестре (в отсутствие Active Directory), либо в Active Directory. Драйвер DFS принимает клиентский запрос и переадресует его системе, на которой находится запрошенный файл.

Ha клиентской стороне поддержка DFS реализована в драйвере MUP (о нем мы уже рассказывали) и использует редиректор CIFS для взаимодействия с серверами DFS на внутреннем уровне. Провайдер клиента DFS реализован в \Windows\System32\Ntlanman.dll. Когда клиент выдает запрос на ввод-вывод для файла в пространстве имен DFS, драйвер MUP на клиентской стороне взаимодействует с сервером, на котором находится этот файл, через подходящий редиректор.

Резюме

Сетевая архитектура Windows предоставляет гибкую инфраструктуру сетевым API, драйверам протоколов и сетевых адаптеров. Эта архитектура использует преимущества многоуровневого ввода-вывода, обеспечивая расширяемость сетевой поддержки по мере развития компьютерных сетей. При появлении нового протокола разработчики смогут создать транспорт TDI, реализующий этот протокол в Windows. Аналогичным образом новые API смогут взаимодействовать с существующими драйверами протоколов Windows. Наконец, набор сетевых API, реализованных в Windows, позволяет разработчикам сетевых приложений выбирать подходящие им реализации, поддерживающие разные модели программирования и протоколы.