Druckversion

Remote Procedure Call

Übersicht Weiter

Der Remote Procedure Call (RPC) ist ein Protokoll, das die Implementierung verteilter Anwendungen - also Netzwerkdienste - vereinfachen soll. Die dahinter steckende Idee ist, dass ein Programm eine Funktion eines Programms, das auf einem anderen Rechner läuft, nutzen kann, ohne sich um die zu Grunde liegenden Netzwerkdetails kümmern zu müssen. Der RPC arbeitet nach dem Client-Server-Modell.

Ein RPC-Aufruf arbeitet in den meisten Fällen synchron. Das lokale Programm, der Client, sendet eine Anforderung an das entfernte Programm, den Server, und unterbricht seine Arbeit bis zum Eintreffen der Antwort. In Verbindung mit Threads ist allerdings eine asynchrone Realisierung eines entfernten Funktionsaufrufs möglich.

Die Programmierung eines Programms, das RPC-Aufrufe verwendet, gestaltet sich recht einfach. In dem der Sprache C sehr ähnlichen Programmcode wird eine so genannte Stub-Routine verwendet, die als Platzhalter für den kompletten Code zur Realisierung des Netzwerkzugriffs dient. Später wird mit Hilfe des Programms rpcgen aus der Datei ein vollständiges C-Programm erzeugt.

RPC-Standards Zurück Anfang Weiter

Ursprünglich wurde das Protokoll von der Firma Xerox entwickelt. Heute existieren eine Reihe von Modellen und Implementierungen von Remote Procedure Calls, u.a.:

ONC RPC

Eine der ersten kommerziell verfügbaren Implementierungen wurde durch die Firma Sun verwirklicht. Das zunächst als SunRPC bezeichnete Modell liegt heute in zwei Implementierungen vor, ONC RPC (Open Network Computing; u.a. von Linux verwendet) und der hauptsächlich mit Solaris verbreitete TI RPC (transport independent). Während erstgenannter RPC einzig die Protokolle TCP und UDP unterstützt, kann der TI RPC auf einigen weiteren Transportprotokollen aufgesetzt werden.

Die Programmiersprache des ONC RPC ist die Remote Procedure Call Language »RPCL«. Des Weiteren werden drei Authentifzierungs-Schemata unterstützt: keine Authentifizierung (Voreinstellung), die Rechteprüfung über UID/GID und SecureRPC, eine Erweiterung, die auf DES-verschlüsselten Zeitstempeln basiert.

DCE RPC

Der RPC des Distributed Computing Environment ist weit weniger verbreitet als der ONC RPC und unter Linux ist keine Implementierung vorhanden. Der Unterschied zum ONC RPC liegt vor allem in der Aufrufsemantik.

DCE RPC - Anwendungen werden mit Hilfe der Interface Definition Language »IDL« programmiert. Die gebräuchlichste Authentifizierungsmethode ist Kerberos.

ISO RPC

Der Versuch der International Organization for Standardization die existierenden Modelle mit einem verbindlichen Standard unter einen Hut zu bringen, scheiterte kläglich. Bis heute existiert keine nennenswerte kommerzielle Implementierung dieses Modells.

Neben der Standardisierung der RPC-Interaktion und -Kommunikation definierte die ISO die Interface Definition Notation »IDN«, eine Sprache zur Erzeugung von RPC-Anwendungen.

Probleme mit RPCs Zurück Anfang Weiter

Da es sich nicht um einen lokalen Funktionsaufruf handelt, ergeben sich mit RPC's eine Reihe von Problemen, deren wichtigste kurz vorgestellt werden sollen:

Zunächst stellt sich die Frage: »Welcher Rechner bietet einen entsprechenden Dienst an?«

Unter Linux erfordern viele auf RPC basierende Dienste die konkrete Angabe des Servers. Andere Dienste verwenden Konfigurationsdateien, in denen die entsprechenden Server eingetragen sind. Eine weitere Möglichkeit ist die Verwendung eines Broadcast-Protokolls, das versucht, einen Server zu finden. Ein verbreitetes Protokoll ist z.B. das Ressource Location Protocol »RLP«.

Welches Transportprotokoll (TCP/UDP/andere) soll verwendet werden?

Hinter der Frage steht die Problematik der Sicherheit und Performance eines RPC-Aufrufs. Eine TCP-basierte Übertragung stellt die Unversehrheit der übertragenen Daten sicher, d.h. dass der Client sich nicht um die Sicherung des Datentransports zu kümmern hat. Da die TCP-Kommunikation synchron abläuft, arbeitet sie in vielen Fällen wesentlich langsamer als das paketorientierte UDP-Protokoll.

RPC-Dienste mit Anfragecharakter (z.B. NIS) werden daher meist über UDP abgewickelt. TCP wird bei intensivem Datentransfer wie NFS häufig eingesetzt. Einige Server unterstützen auch Multiprotokolle, wobei es dem Client überlassen ist, ob er eine Anfrage über TCP oder UDP stellt.

Was ist bei Ausfall des Dienstanbieters (Server)?

Bei einem lokalen Prozeduraufruf ist mit dem Rücksprung aus dieser die Abarbeitung beendet. Was aber, wenn der RPC-Aufruf nicht terminiert? Die Ursachen können vielgestaltig sein: der Server könnte ausgefallen oder überlastet sein, die Netzwerkverbindung könnte gestört sein...

Die meisten Realisierungen von Servern sehen keinerlei Statusinformationen auf Serverseite vor, d.h. die Fehlerbehandlung bleibt allein dem RPC-Client vorbehalten. Üblich sind Timeouts zur Erkennung von Problemen.

Semantik des Aufrufs (genau einmal, mindestens einmal)

Wie verhält sich ein Client, wenn der Server nicht rechtzeitig antwortet? Sendet er den Auftrag ein weiteres Mal ab, oder wartet er ggf. bis in alle Ewigkeit?

ONC RPC und DCE RPC bieten beide verschiedene Semantiken des Aufrufs. Welcher tatsächlich angewandt wird, hängt von der konkreten Realisierung ab. Werden z.B. serverseitig die Anforderungen der Clients verwaltet, so sollte ein Client einen Aufruf tatsächlich nur einmal initiieren dürfen. Merkt sich der Server den Zustand nicht, kann ein Client auch mehrfach eine Anfrage an diesen stellen, ohne dass dessen Arbeit beeinflusst werden würde. Beide RPC-Varianten ermöglichen auch Broadcast-RPCs, wo ein Client gleichzeitig Anfragen an mehrere Server richten kann und »No response«-RPC, wo der Client keine Antwort der Anfrage vom Server erwartet.

Der ISO-RPC lässt nur den einmaligen Aufruf einer RPC-Routine zu.

Wie werden Daten dargestellt (Wortbreite, big endian, little endian)?

Der Aufruf einer RPC-Funktion auf einer Intel-Maschine sollte im Idealfall auch von einem Server, der z.B. auf einer SPARC-Station läuft, behandelt werden können. Das Problem hierbei ist, dass beide Architekturen verschiedene Darstellungsformate verwenden. Nicht nur, dass neuere SPARCs mit einer 64 bit-Wortbreite und Intel-Rechner nach wie vor mit 32 bit arbeiten, sie ordnen intern die Bytes eines Wortes auch noch in unterschiedlichen Reihenfolgen an. Im Falle des RPC ist deshalb das Format der auszutauschenden Daten »big endian« durch das XDR-Protokoll (External Data Representation) fest vorgegeben.

Anordnung der Bytes eines Wortes

Abbildung 1: Byteanordnung auf SPARC und Intel

Wie gut ist die Performance?

Die Geschwindigkeit eines lokalen Funktionsaufrufes zu erreichen, ist ohnehin eine Wunschvorstellung. Dennoch sollte die Verzögerung durch den Netzwerktransport in akzeptablen Grenzen gehalten werden. Um trotz hoher Last die ständige Verfügbarkeit eines Servers zu gewährleisten, werden oft mehrere Serverprozesse parallel gestartet.

Wie steht es mit der Sicherheit ?

Zum einen sollte ein Server wissen, ob ein Client berechtigt ist, seine Dienste in Anspruch zu nehmen. Aber auch der Client möchte sicher gehen, dass er nicht von einem falschen Dienstanbieter Daten erhält und dass er seine Pakete an einen vertrauenswürdigen Rechner sendet. Ebenso kennen RPC-Implementierungen die Verschlüsselung von Daten während der Übertragung, um dem unerlaubten Abhören vorzubeugen.

RPC-Ablauf Zurück Anfang Weiter

Normalerweise erfolgt ein Aufruf einer RPC-Routine synchron, d.h. der Client sendet die Daten an einen Server und schläft bis zum Eintreffen der Antwort.

Der Server überwacht im einfachsten Fall den ihm zugedachten Port und beginnt, sobald er eine Anforderung eines Clients erkennt, mit der Bearbeitung des Auftrags. Dazu entpackt er die Daten des Pakets, ruft die behandelnde Routine auf, verpackt das Ergebnis und sendet die Antwort an den Client. Anschließend wartet der Server auf neue Aufträge. Abbildung 2 skizziert diesen einfachsten Fall.

Prinzip eines RPC-Calls

Abbildung 2: Ablauf eines RPC-Aufrufs

Wo liegt das Problem? Es existieren eine ganze Reihe von Standard-RPC-Diensten und von vielen Diensten bieten manche Server auch noch mehrere Versionen an. Wie also identifiziert ein Client den entsprechenden Dienst auf dem Server?

Ein RPC-Dienst wird durch genau drei Parameter eindeutig beschrieben:

  1. Programmnummer
  2. Versionsnummer
  3. Transportprotokoll

Jeder RPC-Funktion einen eigenen, wohldefinierten Port zuzuweisen, war das Vorgehen in den allerersten Implementierungen. Aber schon bald stieß man auf das Problem der allmählich zur Neige gehenden freien Portnummern...

Die Lösung fand man durch Einführung eines neuen RPC-Dienstes, dessen Aufgabe die dynamische Zuweisung einer freien Portnummer zu einem lokalen Dienst ist, sobald eine Anforderung von einem Client eintrifft.

Bei diesem Dienst handelt es sich um den so genannten Portmapper.

Portmapper Zurück Anfang

An welchem Port der Portmapper auf Anforderungen lauscht, muss für jede Client-Anwendung bekannt sein. Deswegen überwacht der Portmapper stets Port 111 sowohl über TCP als auch UDP.

Alle RPC-Dienste, die der eigene Rechner anbieten soll, müssen ihre Bereitschaft dem Portmapper signalisieren. Das impliziert, dass vor dem Start eines jeden RPC-Dienstes der Portmapper zu starten ist.

In jeder Linux-Distribution sollte das Programm portmap existieren, üblicherweise im Verzeichnis »/sbin«. Falls der Portmapper noch nicht aktiv ist, kann der Administrator diesen von Hand starten:

root@sonne> /sbin/portmap

Die Arbeit des Portmappers lässt sich mit Hilfe des Kommandos rpcinfo überprüfen:

root@sonne> rpcinfo -p
   program vers proto   port
    100000    2   tcp    111  portmapper
    100000    2   udp    111  portmapper

An obiger Ausgabe ist zu erkennen, dass der Portmapper zurzeit der einzige aktive RPC-Dienst ist.

Sobald der Prozess des Portmappers läuft, überwacht er den Port 111 auf eintreffende Verbindungswünsche. Gleichzeitig führt er eine Tabelle mit allen notwendigen Informationen zu lokalen RPC-Diensten, die sich bei ihm registriert haben.

Trifft nun eine Anfrage von einem Client ein, schaut der Portmapper in seinen Tabellen nach, ob der erwünschte Dienst in der entsprechenden Version registriert ist. Wenn ja, antwortet er dem Client mit der korrekten Portnummer, an der der Server-Prozess aktiv ist. Der Client wendet sich des Weiteren direkt an den Server. Für weitere Anfragen wird dessen Portnummer lokal für eine gewisse Zeit zwischen gespeichert. Der Ablauf ist nochmals in Abbildung 3 skizziert:

Anfrage eines Client beim Portmapper

Abbildung 3: RPC-Client erfragt die Portnummer des Servers

 Korrekturen, Hinweise?
Startseite Nächste Seite Nächstes Kapitel Vorherige Seite Kapitelanfang