Fix: не запускается служба "Удаленный вызов процедур (RPC)". RPC, Messaging, REST: Терминология Протокол rpc

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

Удаленный вызов процедур: что это?

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

Однако удаленные процедуры (вызов удаленных процедур), обозначаемые как RPC (сокращение от английского Remote Procedure Call), можно отнести не только к удаленным компьютерам. На локальном уровне такие технологии тоже применяются. В качестве простейшего примера можно привести вызов определенной функции одной программы из другого приложения посредством взаимодействия через специальные библиотеки.

Кроме того, абсолютно во всех версиях Windows имеется такая служба, а при ее отключении или отказе работоспособности модификация XP не работает вообще.

Принцип действия

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

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

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

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

Удаленные процедуры (вызов удаленных процедур): характерные черты и реализации

Таким образом, можно выделить две главные особенности названных технологий:

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

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

  • DCE/RPC - бинарный протокол на основе TCP/IP, SMB/SIFC и т. д.;
  • DCOM - объектно-ориентированное дополнение с возможностью передачи ссылок на объекты и вызовом методов их обработки;
  • JSON-RPC - текстовый протокол, основанный на HTTP;
  • .NET Remoting - бинарный протокол на основе UDP, TCP и HTTP;
  • JAVA RMI;
  • SOAP;
  • XML RPC;
  • SUN RPC;
  • ZeroC ICE;
  • Routix.RPC и др.

Проблемы и задачи

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

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

Наконец, одной из основных называется проблема совместимости ввиду неоднородности некоторых языков программирования, несмотря даже на установленные единые стандарты.

Основные типы подсистем

Удаленный вызов процедур Windows 10 или любой другой системы рангом ниже подразумевает использование специальных подсистем:

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

Какие типы программ требуют выполнения RPC?

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

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

Думается, этого списка достаточно, чтобы понять, насколько многие компоненты системы, да и сам пользователь, зависимы от этой службы.

На что влияет RPC

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

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

Можно ли отключить эту службу

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

Но не все знают, что в разделе службы (services.msc) есть еще такая штука, как «Локатор удаленного вызова процедур RPC». Вот его-то как раз и можно отключить безболезненно для системы. Приложения, которые могут его использовать в своей работе, самостоятельно вызовут сервис при необходимости.

Устранение сбоев и ошибок

Наконец, посмотрим, что можно сделать, если выдается ошибка при удаленном вызове процедуры. В самом простом случае можно попытаться включить службу заново (если, конечно, получится).

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

Если это не поможет, но под рукой имеется установочный или восстановительный диск системы, можно запустить командную консоль с правами администратора (загружаться с диска не нужно) и прописать в ней такие команды:

  • cd z:\i386 (Z - литера оптического привода) ;
  • expand explorer.ex_ %TEMP%\explorer.exe;
  • expand svchost.ex_ %TEMP%\svchost.exe.

После этого запускаем «Диспетчер задач» (Ctrl + Del + Alt или taskmgr в меню «Выполнить») и завершаем процесс Explorer.exe.

В «Диспетчере» останавливаем все процессы svhost.exe, после чего в течение 60 секунд нужно успеть в командой строке ввести строку copy %TEMP%\svchost.exe %systemroot%\system32 /y.

Наконец, если есть доступ к редактору системного реестра (regedit) восстановлен, нужно пройти по ветке HKCC через разделы SYSTEM и CurrentControlSet и добраться до параметра CSConfigFlags, изменив его значение на ноль.

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

Заключение

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

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

В состав операционной системы Windows любой модификации, начиная с версии ХР, входит служебный компонент, обозначаемый как RPC. Что это такое, рядовые пользователи в большинстве своем не знают, тем более, не догадываются, для чего нужна эта служба и как она работает. В связи с этим предлагается рассмотреть некоторые основные аспекты, связанные с самим компонентом, принципами его работы и областью использования без описания ненужных и сложных технических терминов. Отдельно остановимся на возможных ошибках службы и методиках их быстрого устранения.

Удаленные процедуры (вызов удаленных процедур): что это такое?

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

То есть запрос формируется на одном терминале, затем передается на другой, где и выполняется, после чего на первый компьютер возвращается ответ (отчет) о выполнении. Но это только примитивное пояснение. На самом деле, все намного сложнее, поскольку здесь нужно учитывать протоколы передачи данных (UDP, TCP, HTTP) и многие другие механизмы.

Для чего нужна эта служба?

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

Например, в настройках секвенсора FL Studio можно указать другое приложение (скажем, Adobe Audition), которое для редактирования звуковых файлов (сэмплов) в среде основной программы будет использоваться по умолчанию. При этом подключение Adobe Audition к FL Studio будет осуществляться не через виртуальные хосты вроде VST, RTAS или DX, а непосредственно через задействование службы удаленного вызова процедур. Само собой разумеется, что этот пример не единственный, поскольку область применения описываемого компонента гораздо шире.

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

Сбой при удаленном вызове процедуры: в чем причина?

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

Вследствие этого становится невозможным не только использование самого компонента. Иногда даже не удается получить доступ к некоторым системным настройкам, а Windows ХР так и вовсе «слетает», после чего восстановить ее до нормального работоспособного состояния бывает достаточно проблематично. Еще одна проблема - инструмент онлайн-восстановления DISM, входящий в состав операционной системы.

Именно с нарушениями в его работе связывают появление ошибки 1726, которая непосредственно влияет и на функционирование компонентов службы RPC.

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

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

Можно ли отключить службу RPC?

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

Последствия отключения процессов RPC

Даже если пользователю удастся каким-то образом отключить удаленные процедуры (вызов удаленных процедур), последствия, к сожалению, могут быть самыми непредсказуемыми. Как уже говорилось, Windows XP может вообще перестать работать, а в ОС рангом выше, как следствие, может появиться огромное количество системных сбоев, которые устранить не получится хотя бы по причине отсутствия доступа к критически важным настройкам и параметрам Windows, причем, даже в безопасном режиме или при старте со съемного носителя. Тем не менее, сбой при вызове удаленных процедур в Windows 10 или более ранних версиях операционной системы исправить можно. Метод не самый простой, поэтому при его использовании нужно быть очень внимательным.

Отключение локатора удаленного доступа

Итак, основную службу RPC отключать нельзя. Но, может быть, есть смысл деактивировать некоторые из ее сопутствующих компонентов? Да, действительно, если зайти в раздел системных служб и их компонентов (services.msc), в нем можно найти так называемый локатор RPC.

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

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

  • cd X:\i386 (X - буква съемного диска);
  • expand explorer.ex_ %TEMP%\explorer.exe;
  • expand svchost.ex_ %TEMP%\svchost.exe.

После перезагрузки вызывается «Диспетчер задач», и в нем завершается затем в командной строке прописывается сочетание copy %TEMP%\explorer.exe %SYSTEMROOT% /y, после чего в «Диспетчере задач» завершаются абсолютно все процессы svchost. Теперь следует быть особо внимательным, поскольку по завершении процессов в течение всего лишь шестидесяти секунд в командной консоли нужно успеть прописать команду copy %TEMP%\svchost.exe %systemroot%\system32 /y.

Если у пользователя, например, в обычном или в безопасном режиме есть доступ к системному реестру, в редакторе (regedit) в ветке HKCC необходимо найти параметр CSConfigFlags и присвоить ему значение в виде нуля.

Устранение сбоя 1726

Наконец, устранение ошибки 1726 также производится через реестр. Но в данном случае в ветке HKLM нужно найти каталог RpcSs, а справа отредактировать значение параметра Start.

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

Послесловие

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

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

Очень важный механизм для приложений "клиент-сервер" обеспечивается RPC (Remote Procedure Call ). RPC был разработан Sun Micrsystems, и эта система представляет собой набор инструментальных средств и библиотечных функций. В частности на RPC работают NIS (Network Information System) и NFS (Network File System).

Сервер RPC состоит из системы таких процедур, что клиент может обратится, посылая RPC-запрос к серверу вместе с параметрами процедуры. Сервер вызовет обозначенную процедуру и вернет значение возврата процедуры, если оно есть. Чтобы быть машинно-независимыми, все данные, которыми обмениваются клиент и сервер, преобразуются к так называемому внешнему представлению данных (External Data Representation , XDR). RPC связан с сокетами UDP и TCP для передачи данных в формате XDR. Sun объявила RPC как public domain, и его описание доступно в серии документов RFC.

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

Сетевая связь между серверами и клиентами RPC немного особая. RPC-сервер предлагает одну или более системных процедур, каждое множество таких процедур называется программой (program ) и однозначно идентифицировано номером программы (program number ). Список имен сервисов обычно хранится в /etc/rpc , пример которого приведен ниже.

Пример 12-4. Образец файла /etc/rpc

# # /etc/rpc - miscellaneous RPC-based services # portmapper 100000 portmap sunrpc rstatd 100001 rstat rstat_svc rup perfmeter rusersd 100002 rusers nfs 100003 nfsprog ypserv 100004 ypprog mountd 100005 mount showmount ypbind 100007 walld 100008 rwall shutdown yppasswdd 100009 yppasswd bootparam 100026 ypupdated 100028 ypupdate

В TCP/IP сетях перед авторами RPC стояла задача отображения номеров программ на общие сетевые услуги. Каждый сервер обеспечивает TCP и UDP порт для каждой программы и каждой версии. Вообще, RPC-приложения используют UDP для передачи данных и возвращаются обратно к TCP тогда, когда данные, которые надо передать, не вписываются в единственную датаграмму UDP.

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

Этот метод имеет тот недостаток, что вводит единственную точку отказа, очень похожую на inetd daemon. Однако, этот случай немного хуже, потому что когда portmapper валится, вся информация RPC о портах теряется. Это обычно значит, что Вы должны перезапустить все RPC-серверы вручную или перезагрузить машину.

В Linux portmapper называется /sbin/portmap или /usr/sbin/rpc.portmap . Кроме того, что он должен быть запущен из скрипта запуска сети, рortmapper не требует никакой работы по конфигурации.

После перезагрузки компа не запустилась служба "Удаленный вызов процедур (RPC) ". Очень многое зависит от этой службы. В итоге не работает восстановление системы, сетевое окружение, звук, Windows Installer, почти не работает консоль управления (MMC), на панели задач не показываются открытые окна и т.д. и т.п. Попытка ручного запуска приводит к ошибке "Неудается запустить...(RPC) на xxxComp. Ошибка 5: Отказано в доступе ". Антивирус ничего не нашел. Два дня копаний и комп удалось вернуть к жизни.

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

Далее, попытка восстановить параметры службы в реестре. Поскольку regedit.exe работал только на чтение/удаление (еще один побочный эффект), не получилось внести изменения. Да они и не нужны были, т.к. все было верно. Должно выглядеть вот так:

Windows Registry Editor Version 5.00 "Description"="Обеспечивает сопоставление конечных точек и иных служб RPC." "DisplayName"="Удаленный вызов процедур (RPC)" "ErrorControl"=dword:00000001 "Group"="COM Infrastructure" "ImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\ 74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,\ 00,76,00,63,00,68,00,6f,00,73,00,74,00,20,00,2d,00,6b,00,20,00,72,00,70,00,\ 63,00,73,00,73,00,00,00 "ObjectName"="NT AUTHORITY\\NetworkService" "Start"=dword:00000002 "Type"=dword:00000010 "FailureActions"=hex:00,00,00,00,00,00,00,00,00,00,00,00,01,00,00,00,00,00,00,\ 00,02,00,00,00,60,ea,00,00 "ServiceSidType"=dword:00000001 "ServiceDll"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,\ 00,74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\ 72,00,70,00,63,00,73,00,73,00,2e,00,64,00,6c,00,6c,00,00,00 "Security"=hex:01,00,14,80,a8,00,00,00,b4,00,00,00,14,00,00,00,30,00,00,00,02,\ 00,1c,00,01,00,00,00,02,80,14,00,ff,01,0f,00,01,01,00,00,00,00,00,01,00,00,\ 00,00,02,00,78,00,05,00,00,00,00,00,14,00,8d,00,02,00,01,01,00,00,00,00,00,\ 05,0b,00,00,00,00,00,18,00,ff,01,0f,00,01,02,00,00,00,00,00,05,20,00,00,00,\ 20,02,00,00,00,00,18,00,8d,00,02,00,01,02,00,00,00,00,00,05,20,00,00,00,23,\ 02,00,00,00,00,14,00,9d,00,00,00,01,01,00,00,00,00,00,05,04,00,00,00,00,00,\ 18,00,9d,00,00,00,01,02,00,00,00,00,00,05,20,00,00,00,21,02,00,00,01,01,00,\ 00,00,00,00,05,12,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00 "0"="Root\\LEGACY_RPCSS\\0000" "Count"=dword:00000001 "NextInstance"=dword:00000001

Значение параметра start может отличаться. Изменить реестр все же можно, но при этом нужно загрузиться с MS ERD commander .

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

  • Запустить консоль (Пуск > Выполнить: cmd )
  • cd z:\i386 (там дистрибутив Windows)
  • expand explorer.ex_ %TEMP%\explorer.exe
  • expand svchost.ex_ %TEMP%\svchost.exe
  • Запустить Диспетчер задач (Ctrl+Shift+Esc)
  • Остановить процесс exlporer.exe
  • copy %TEMP%\explorer.exe %SYSTEMROOT% /y
  • Остановить все процессы svchost.exe. Внимание! После этого у вас будет 60 секунд до перезагрузки машины.
  • copy %TEMP%\svchost.exe %systemroot%\system32 /y

Этот финт тоже не дал результатов. Еще вариант: запустить проверку всех защищенных системных файлов с заменой неправильных версий правильными. В консоли выполнить:

sfc /PURGECACHE - Очистка файлового кэша и немедленная проверка файлов
sfc /SCANONCE - Разовая проверка при следующей загрузке

Не помогло.. Тогда совсем брутальный ход - восстановление параметров безопасности. Опять же в консоли:

secedit /configure /cfg %windir%\repair\secsetup.inf /db secsetup.sdb /verbose

После перезагрузки комп заработал, базовые сервисы стартовали. Появился новый косяк (а может он был с самого начала): под моей учеткой не запускался, как минимум, менеджер управления дисками и Windows Installer. Отказано в доступе. Можно через консоль восстановить права доступа к системному диску "по умолчанию":

secedit /configure /db %TEMP%\temp.mdb /Cfg %WINDIR%\inf\defltwk.inf /areas filestore

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

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

Что еще можно было предпринять

Пока комп "болел" вот этого не было в реестре:

"ActiveService"="RpcSs"

Возможно ручное добавление как-то бы изменило ситуацию.

Попытки ручного запуска сервиса, например через команду "net start rcpss " заканчивались ошибкой "Error 5: access denied ". Я предполагаю, отказано в доступе потому, что сервис должен запускаться под учеткой системы - "NT AUTHORITY". В реестре есть такой параметр:

"ObjectName"="NT AUTHORITY\\NetworkService"

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

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

Похожие материалы:

Механизм вызова удаленных процедур - RPC

Программы, общающиеся через сеть, нуждаются в механизме связи. На нижнем уровне по поступлении пакетов подается сигнал, обрабатываемый сетевой программой обработки сигналов. На верхнем уровне работает механизм rendezvous (рандеву), принятый в языке Ада. В NFS используется механизм вызова удаленных процедур (RPC), в котором клиент взаимодействует с сервером (см. Рисунок 1). В соответствии с этим процессом клиент сначала обращается к процедуре, посылающей запрос на сервер. По прибытии пакета с запросом сервер вызывает процедуру его вскрытия, выполняет запрашиваемую услугу, посылает ответ, и управление возвращается клиенту.

Интерфейс RPC можно представить состоящим из трех уровней:

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

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

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

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

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

RPC (Remote Procedure Call, Сервис вызова удаленных процедур) представляет собой интерфейс между удаленными пользователями и определенными программами хоста, которые запускаются по запросам этих пользователей. Сервис RPC какого-либо хоста, как правило, предоставляет клиентам комплекс программ. Каждая из таких программ состоит, в свою очередь, из одной или нескольких удаленных процедур. Например, сервис удаленной файловой системы NFS, который построен на вызовах RPC, может состоять только из двух программ: например, одна программа взаимодействует с высокоуровневыми пользовательскими интерфейсами, а другая - с низкоуровневыми функциями ввода-вывода.

В каждом вызове удаленной процедуры участвуют две стороны: активный клиент, который отправляет запрос вызова процедуры на сервер, и сервер, который отправляет клиенту ответ.

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

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

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

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

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

Однако между вызовами локальных и удаленных процедур есть несколько важных отличий:

1. Обработка ошибок. Клиент в любом случае должен получать уведомление об ошибках, возникающих при вызовах удаленных процедур на сервере или в сети.

2. Глобальные переменные. Поскольку сервер не имеет доступа к адресному пространству клиента, при вызовах удаленных процедур нельзя использовать скрытые параметры в виде глобальных переменных.

3. Производительность. Скорость выполнения удаленных процедур, как правило на один или два порядка ниже скорости выполнения аналогичных локальных процедур.

4. Аутентификация. Поскольку вызовы удаленных процедур происходят по сети, необходимо использовать механизмы аутентификации клиента.

Принципы построения протокола.

Протокол RPC может использовать несколько различных транспортных протоколов. В обязанности RPC-протокола входит только обеспечение стандартов и интерпретация передачи сообщений. Достоверность и надежность передачи сообщений целиком обеспечивается транспортным уровнем.

Однако RPC может контролировать выбор и некоторые функции транспортного протокола. В качестве примера взаимодействия между RPC и транспортным протоколом рассмотрим процедуру назначения RPC-порта работы прикладного процесса через RPC - Portmapper .

Эта функция динамически (по запросу) назначает соединению RPC определенный порт. Функция Portmapper используется довольно часто, поскольку набор зарезервированных для RPC транспортных портов ограничен, а количество процессов, которые потенциально могут одновременно работать очень высоко. Portmapper , например, вызывается при выборе портов взаимодействия клиента и сервера системы NFS.

Сервис Portmapper использует механизм широковещательных сообщений RPC на определенный порт - III. На этот порт клиент отправляет широковещательное сообщение запроса порта определенного сервиса RPC. Сервис Portmapper обрабатывает таксе сообщение, определяет адрес локального сервиса RPC и отправляет клиенту ответ. Сервис RPC Portmapper может работать как с TCP, так и с UDP-протоколами.

RPC может работать с различными транспортными протоколами, но никогда не дублирует их функции, т. е. если RPC работает поверх TCP, все заботы о надежности и достоверности соединения RPC возлагает на TCP. Однако, если протокол RPC установлен поверх UDP, он может обеспечивать дополнительные собственные функции обеспечения гарантированной доставки сообщений.

Примечание. Прикладные задачи могут рассматривать RPC-протокол как определенную процедуру вызова функции по сети JSR (Jump Subroutine Instruction).

Для работы RPC-протокола необходимо выполнение следующих условий:

1. Уникальная идентификации всех удаленно вызываемых процедур на данном хосте. RPC-запросы содержат три поля идентификаторов - номер удаленной программы (сервиса), номер версии удаленной программы и номер удаленной процедуры указанной программы. Номер программы назначается производителем сервиса, номер процедуры указывает на конкретную функцию данного сервиса

2. Идентификация версии RPC-протокола. RPC-сообщения содержат поле версии RPC-протокола. Она используется для согласования форматов передаваемых параметров при работе клиента с различными версиями RPC.

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

RPC может использовать четыре типа механизмов аутентификации:

AUTH_NULL - без использования аутентификации

AUTH_UNIX - аутентификация по стандарту UNIX

AUTH_SHORT - аутентификация по стандарту UNIX с собственной структурой кодирования

AUTH_DES - аутентификация по стандарту DES

4. Идентификация сообщений ответа на соответствующие запросы. Ответные сообщения RPC содержат идентификатор запроса, на основании которого они были построены. Этот идентификатор можно назвать идентификатором транзакции вызова RPC. Данный механизм особенно необходим при работе в асинхронном режиме и при выполнении последовательности из нескольких RPC-вызовов.

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

Структуры сообщений протокола

При передаче RPC-сообщений поверх транспортного протокола, несколько RPC-сообщений могут располагаться внутри одного транспортного пакета. Для того чтобы отделять одно сообщение от другого, используется маркер записи (RM - Record Marker). Каждое RPC-сообщение "маркируется" ровно одним RM.

RPC-сообщение может состоять из нескольких фрагментов. Каждый фрагмент состоит из четырех байт заголовка и (от 0 до 2**31-1) данных. Первый бит заголовка указывает, является ли данный фрагмент последним, а остальные 31 бит указывают длину пакета данных.

Структура RPC формально описана на языке описания и представления форматов данных - XDR с дополнениями, касающимися описания процедур. Можно даже сказать, что язык описания RPC является расширением XDR, дополненным работой с процедурами.

Структура RPC-пакета выглядит следующим образом:

struct rpc_msg {

unsigned int xid;

union switch (msg_type mtype) {

call_body cbody;

reply body rbody;

где xid - идентификатор текущей транзакции, call_body - пакет запроса, reply_body - пакет ответа. Структура запроса выглядит примерно так:

struct call body {

unsigned int rpcvers;

unsigned int prog;

unsigned int vers;

unsigned int proc;

opaque_auth cred;

opaque_auth verf;

/* procedure parameters */

Структура ответа (reply_body) может содержать либо структуру, передаваемую в случае ошибки (тогда она содержит код ошибки), либо структуру успешной обработки запроса (тогда она содержит возвращаемые данные).

Программный интерфейс высокого уровня.

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

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

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

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

Удаленный вызов процедуры включает следующие шаги:

1. Программа-клиент производит локальный вызов процедуры, называемой заглушкой (stub). При этом клиенту "кажется", что, вызывая заглушку, он производит собственно вызов процедуры-сервера. И действительно, клиент передает заглушке необходимые параметры, а она возвращает результат. Однако дело обстоит не совсем так, как это себе представляет клиент. Задача заглушки - принять аргументы, предназначаемые удаленной процедуре, возможно, преобразовать их в некий стандартный формат и сформировать сетевой запрос. Упаковка аргументов и создание сетевого запроса называется сборкой (marshalling).

2. Сетевой запрос пересылается по сети на удаленную систему. Для этого в заглушке используются соответствующие вызовы, например, рассмотренные в предыдущих разделах. Заметим, что при этом могут быть использованы различные транспортные протоколы, причем не только семейства TCP/IP.

3. На удаленном хосте все происходит в обратном порядке. Заглушка сервера ожидает запрос и при получении извлекает параметры - аргументы вызова процедуры. Извлечение (unmarshalling) может включать необходимые преобразования (например, изменения порядка расположения байтов).

4. Заглушка выполняет вызов настоящей процедуры-сервера, которой адресован запрос клиента, передавая ей полученные по сети аргументы.

5. После выполнения процедуры управление возвращается в заглушку сервера, передавая ей требуемые параметры. Как и заглушка клиента; заглушка сервера преобразует возвращенные процедурой значения, формируя сетевое сообщение-отклик, который передается по сети системе, от которой пришел запрос.

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

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

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

Передача параметров

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

Связывание (binding)

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

Нахождение удаленного хоста с требуемым сервером

Нахождение требуемого серверного процесса на данном хосте

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

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

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

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

Обработка особых ситуаций (exception)

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

Например, при использовании UDP в качестве транспортного протокола производится повторная передача сообщений после определенного тайм-аута. Клиенту возвращается ошибка, если, спустя определенное число попыток, отклик от сервера так и не был получен. В случае, когда используется протокол TCP, клиенту возвращается ошибка, если сервер оборвал TCP-соединение.

Семантика вызова

Вызов локальной процедуры однозначно приводит к ее выполнению после чего управление возвращается в головную программу. Иначе дело обстоит при вызове удаленной процедуры. Невозможно установить, когда конкретно будет выполняться процедура, будет ли она выполнена вообще, а если будет, то какое число раз? Например, если запрос будет получен удаленной системой после аварийного завершения программы сервера, процедура не будет выполнена вообще. Если клиент при неполучении отклика после определенного промежутка времени (тайм-аута) повторно посылает запрос, то может создаться ситуация, когда отклик уже передается по сети, а повторный запрос вновь принимается на обработку удаленной процедурой. В этом случае процедура будет выполнена несколько раз.

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

- Один и только один раз. Данного поведения (в некоторых случаях наиболее желательного) трудно требовать ввиду возможных аварий сервера.

- Максимум раз. Это означает, что процедура либо вообще не была выполнена, либо была выполнена только один раз. Подобное утверждение можно сделать при получении ошибки вместо нормального отклика.

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

Представление данных

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

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

Например, формат представления данных в RPC фирмы Sun Microsystems следующий:

Порядок следования байтов - Старший - последний

Представление значений с плавающей точкой - IEEE

Представление символа - ASCII

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

Программные реализации системы, как правило, поддерживают один или два протокола. Например, система RPC разработки фирмы Sun Microsystems поддерживает передачу сообщений с использованием протоколов TCP и UDP. Выбор того или иного протокола зависит от требований приложения. Выбор протокола UDP оправдан для приложений, обладающих следующими характеристиками:

Вызываемые процедуры идемпотентны

Размер передаваемых аргументов и возвращаемого результата меньше размера пакета UDP - 8 Кбайт.

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

С другой стороны, TCP обеспечивает эффективную работу приложений со следующими характеристиками:

Приложению требуется надежный протокол передачи

Вызываемые процедуры неидемпонентны

Размер аргументов или возвращаемого результата превышает 8 Кбайт

Выбор протокола обычно остается за клиентом, и система по-разному организует формирование и передачу сообщений. Так, при использовании протокола TCP, для которого передаваемые данные представляют собой поток байтов, необходимо отделить сообщения друг от друга. Для этого например, применяется протокол маркировки записей, описанный в RFC1057 "RPC: Remote Procedure Call Protocol specification version 2", при котором в начале каждого сообщения помещается 32-разрядное целое число, определяющее размер сообщения в байтах.

По-разному обстоит дело и с семантикой вызова. Например, если RPC выполняется с использованием ненадежного транспортного протокола (UDP), система выполняет повторную передачу сообщения через короткие промежутки времени (тайм-ауты). Если приложение-клиент не получает отклик, то с уверенностью можно сказать, что процедура была выполнена ноль или большее число раз. Если отклик был получен, приложение может сделать вывод, что процедура была выполнена хотя бы однажды. При использовании надежного транспортного протокола (TCP) в случае получения отклика можно сказать, что процедура была выполнена один раз. Если же отклик не получен, определенно сказать, что процедура выполнена не была, нельзя3.

Как это работает?

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

В качестве примера рассмотрим RPC фирмы Sun Microsystems. Система состоит из трех основных частей:

Rpcgen(1) - RPC-компилятор, который на основании описания интерфейса удаленной процедуры генерирует заглушки клиента и сервера в виде программ на языке С.

Библиотека XDR (eXternal Data Representation), которая содержит функции для преобразования различных типов данных в машинно-независимый вид, позволяющий производить обмен информацией между разнородными системами.

Библиотека модулей, обеспечивающих работу системы в целом.

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

Для этого придется создать как минимум три файла: спецификацию интерфейсов удаленных процедур log.x (на языке описания интерфейса), собственно текст удаленных процедур log.c и текст головной программы клиента main () - client.c (на языке С) .

Компилятор rpcgen(l) на основании спецификации log.x создает три файла: текст заглушек клиента и сервера на языке С (log clnt.c и log svc.c) и файл описаний log.h, используемый обеими заглушками.

Итак, рассмотрим исходные тексты программ.

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

program LOG_PROG {

version LOG_VER {

int RLOG (string) = 1;

} = 0х31234567;

Компилятор rpcgen(l) создает файл заголовков log.h, где, в частности, определены процедуры:

log.h

* Please do not edit this file.

* It was generated using rpcgen.

#ifndef _LOG_H_RPCGEN

#define _LOG_H_RPCGEN

#include

/* Номер программы*/

#define LOG_PROG ((unsigned long) (0х31234567))

#define LOG_VER ((unsigned long) (1)) /*Номер версии*/

#define RLOG ((unsigned long) (1)) /*Номер процедуры*/

extern int *rlog_l () ;

/*Внутренняя процедура - нам ее использовать не придется*/ extern int log_prog_l_freeresult();

#endif /* !_LOG_H_RPCGEN */

Рассмотрим этот файл внимательно. Компилятор транслирует имя RLOG определенное в файле описания интерфейса, в rlog_1, заменяя прописные символы на строчные и добавляя номер версии программы с подчеркиванием. Тип возвращаемого значения изменился с int на int *. Таково правило - RPC позволяет передавать и получать только адреса объявленных при описании интерфейса параметров. Это же правило касается и передаваемой в качестве аргумента строки. Хотя из файла print.h это не следует, на самом деле в качестве аргумента функции rlog_l () также передается адрес строки.

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

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

log.c

#include

#include

#include

#include "log.h"

int *rlog_1 (char **arg)

/*Возвращаемое значение должно определяться как static*/

static int result;

int fd; /*Файловый дескриптор журнала*/

/*0ткроем файл журнала (создадим, если он не существует), в случае неудачи вернем код ошибки result == 1.*/

if ((fd=open("./server .log",

O_CREAT | O_RDWR | O_APPEND)) < 0) return (&result);

len = strlen(*arg);

if (write(fd, *arg, strlen(*arg)) != len)

return(&result); /*Возвращаем результат - адрес result*/

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

client.c

#include

#include "log.h"

main(int argc, char *argv)

char *server, *mystring, *clnttime;

if (argc != 2) {

fprintf(stderr, "Формат вызова: %s Адрес_хоста\n",

/*Получим дескриптор клиента. В случае неудачи - сообщим о

невозможности установления связи с сервером*/

if ((с1 = clnt_create (server,

LOG_PROG, LOG_VER, "udp")) == NULL) {

clnt_pcreateerror (server);

/*Выделим буфер для строки*/

mystring = (char *)malloc (100);

/*Определим время события*/

bintime = time ((time_t *) NULL);

clnttime = ctime(&bintime);

sprintf (mystring, "%s - Клиент запущен", clnttime);

/*Передадим сообщение для журнала - время начала работы клиента. В случае неудачи - сообщим об ошибке*/

if ((result = rlog_l(&mystring, cl)) == NULL) {

fprintf(stderr, "error2\n");

clnt_perror(cl, server);

/*B случае неудачи на удаленном компьютере сообщим об ошибке*/

if (*result !=0)

fprintf(stderr, "Ошибка записи в журнал\n");

/*0свободим дескриптор*/

cint destroy(cl);

Заглушка клиента log_clnt.c компилируется с модулем client.c для получения исполняемой программы клиента.

cc -о rlog client.c log_clnt.c -Insl

Заглушка сервера log_svc.c и процедура log.c компилируются для получения исполняемой программы сервера.

cc -о logger log_svc.c log.c -Insl

Теперь на некотором хосте server.nowhere.ru необходимо запустить серверный процесс:

После чего при запуске клиента rlog на другой машине сервер добавит соответствующую запись в файл журнала.

Схема работы RPC в этом случае приведена на рис. 1. Модули взаимодействуют следующим образом:

1. Когда запускается серверный процесс, он создает сокет UDP и связывает любой локальный порт с этим сокетом. Далее сервер вызывает библиотечную функцию svc_register(3N) для регистрации номеров программы и ее версии. Для этого функция обращается к процессу portmap(IM) и передает требуемые значения. Сервер portmap(IM) обычно запускается при инициализации системы и связывается с некоторым общеизвестным портом. Теперь portmap(3N) знает номер порта для нашей программы и версии. Сервер же ожидает получения запроса. Заметим, что все описанные действия производятся заглушкой сервера, созданной компилятором rpcgen(IM).

2. Когда запускается программа rlog, первое, что она делает, - вызывает библиотечную функцию clnt_create(3N), указывая ей адрес удаленной системы, номера программы и версии, а также транспортный протокол. Функция направляет запрос к серверу portmap(IM) удаленной системы server.nowhere.m и получает номер удаленного порта для сервера журнала.

3. Клиент вызывает процедуру rlog_1 () , определенную в заглушке клиента, и передает управление заглушке. Та, в свою очередь, формирует запрос (преобразуя аргументы в формат XDR) в виде пакета UDP и направляет его на удаленный порт, полученный от сервера portmap(IM). Затем она некоторое время ожидает отклика и в случае неполучения повторно отправляет запрос. При благоприятных обстоятельствах запрос принимается сервером logger (модулем заглушки сервера). Заглушка определяет, какая именно функция была вызвана (по номеру процедуры), и вызывает функцию rlog_1 () модуля log.c. После возврата управления обратно в заглушку последняя преобразует возвращенное функцией rlog_1 () значение в формат XDR, и формирует отклик также в виде пакета UDP. После получения отклика заглушка клиента извлекает возвращенное значение, преобразует его и возвращает в головную программу клиента.