Im Gegensatz zur entfernten Ausführung von Kommandos (Remote Command Execution - RCX) wie z.B. rsh, rcp oder rlogin, muß bei einem RPC-Call im Server-Rechner nicht notwendig ein neuer Prozeß gestartet werden. Die Verbindung wird zu einem bereits laufenden, auf die Anforderung wartenden Prozeß hergestellt, der als Server im engeren Sinne bezeichnet wird. So ein Server-Prozeß kann mehrere ausführbare Prozeduren als Dienste anbieten. Es ist aber ebenfalls möglich, daß in einem Server-Rechner mehrere Server-Prozesse laufen, die verschiedene Arten von Diensten anbieten.
Die entfernten Dienste werden durch Programm- und Prozedurnummer adressiert. RPC ermöglicht zusätzlich eine Unterscheidung zwischen verschiedenen Versionen: In einem Server-Prozeß können gleichzeitig mehrere Versionen der gleichen Prozedur angeboten werden. Damit kann man eine Prozedur-Entwicklung im Netzwerk sinnvoll verwalten. Der Client muß also bei der Adressierung der entfernten Prozedur den Server-Rechner, die Programmnummer, die Versionsnummer und die Prozedurnummer kennen.
Netzwerk Transport-Protokolle, wie z.B (TCP) ermöglichen zusätzlich zu Netzwerkadresse und Hostadresse (bereits in der Netzwerkschicht vorhanden) Adressierungen, die aus sog. Portnummern bestehen.
Transportadresse = Netzwerkadresse + Hostadresse + Portnummer
| |
-----------------------------
|
z.B. IP-Adresse
Bild 9
Unter einem Port versteht man eine Warteschlange mit zwei Semaphoren: für den Eingang und für den Ausgang. Der Transportweg ist durch das Paar (Port des Sender, Port des Empfängers) und nicht nur durch einen Port allein gekennzeichnet. Mit der Portnummer kann ein Prozeß angesprochen werden, der auf die Ankunft einer Message an diesem Port wartet. Diese Tatsache macht sich der RPC-Mechanismus zunutze. Eine direkte Adressierung des Server-Prozesses über die UNIX Prozeß-Id wäre nicht sinnvoll, da der Server-Prozeß nicht immer die gleiche Prozeß-Id haben kann. Er könnte ja z.B. abstürzen und noch einmal gestartet werden.
Eine feste Abbildung der Server-Dienste in die Portnummer hat sich ebenfalls nicht als sinnvoll herausgestellt. Man muß ja auch an andere als lediglich RPC Benutzer der Porte denken. Die flexible Abbildung der Server-Dienste in die Portnummer wird von dem sog. Portmapper realisiert:
(Programmnummer, Prozedurversion) <--> (Protokoll, Portnummer)
Man nennt diese Zuordnung die Bindung (engl. Binding).
Bei RPC werden die Server-Dienste (Prozeduren) nicht durch den Namen sondern durch (Programmnummer, Version, Prozedurnummer) angesprochen. Dem Linker bekannte Prozedurnamen können ja aus dem Kompilat entfernt werden.
-----------------------------------
| Programm PROGNR |
| |
| --------------------------- |
| | Version VERSNR | |
| | | <- | ------> Portnummer
| | ------------------- | |
| | | Prozedur PROCNR | | |
| | ------------------- | |
| | . | |
| | . | |
| --------------------------- |
| . |
| . |
| . |
| -------------------------- |
| | Version VERSNR_2 | |
| | . | |
| | . | |
| -------------------------- |
-----------------------------------
Bild 10
Der Portmapper ist ein Dämon-Prozeß im Server-Rechner, der einmal (z.B. beim Booten des Systems) gestartet wird. Jeder neu gestartete Server-Prozeß muß seine Dienste vom Portmapper registrieren lassen und bekommt dafür eine Portnummer zugewiesen. Sie kann je nach Rechner oder Situation verschieden sein. Der Portmapper wartet selbst immer am gleichen Port (Nummer 111). Alle neuen Client-Requests greifen zuerst auf diesen Port zu, werden jedoch vom Portmapper an den richtigen Port verwiesen, den sie für weitere Kommunikation verwenden. Bei einem Request an einen anderen Server-Dienst wird der Client an einen anderen Port verwiesen. Die Kommunikations-Details dieses Mechanismus werden als Portmapper Protokoll bezeichnet.
Die Prozedurnummer wird nicht registriert, sondern an die registrierte Serviceroutine zur abschließenden Verzweigung weitergereicht.
------------------ -------------------------
| | | |
| | ----------- |
| Client | | Port | Server |
| | | a | |
| | ----------- |
| | | |
| ------------ | ----------- ---------- |
| | | -------------------------> | Port | ---> | Port- | |
| | Client- | | ------> | 111 | <--- | mapper | |
| | | ----------- | ----------- ---------- |
| | Programm | | | | | |
| | | <------ | | ----------- |
| ------------ | | | Registrierung | Port | |
| | | | des Services | b | |
| | | | | ----------- |
| | | | | | |
| | | | | ----------- ----------- |
| | | | ------- | Port | ---> | Server- | |
| | | ---------------> | c | | program | |
| | -------------------- | | <--- | | |
| | ----------- ----------- |
| | | |
------------------ -------------------------
Bild 11
Die Portmapper-Dienste sind mit Zustand (statefull). Nach dem Neustart
des Portmappers müssen alle Server-Prozesse noch einmal registriert werden.
Der aktuelle Zustand des Portmappers kann mit rpcinfo(8c)
abgefragt
werden.
SUN erlaubt dem Anwender Programmnummern zwischen 0x 20 000 000 und 0x 3f fff fff, und reserviert andere für sich (siehe Anhang). Diese Nummer ist es, unter der Server-Prozeß seine Dienste beim Portmapper registriert, und nach der der Client seinen Request anmeldet (well-known-number).
Diese Liste ist nicht vollständig (siehe auch /etc/rpc). Sie wird von SUN immer wieder erweitert. Um eigene Dienste fest eintragen zu lassen, wendet man sich an SUN.
RPC-Nummer (hex) Programm Beschreibung
-------------------------------------------------------------------------
0 - 1fffffff Definiert von SUN
100000 PMAPPROG Portmapper
100001 RSTATPROG remote stats
100002 RUSERSPROG remote users
100003 NFSPROG NFS
100004 YPPROG NIS
100005 MOUNTPROG mount daemon
100006 DBXPROG remote dbx
100007 YPBINDPROG NIS Binder
100008 WALLPROG shutdown msg
100009 YPPASSWDPROG yppasswd server
100010 ETHERSTATPROG ether stats
100011 RQUOTAPROG disk quotas
100012 SPRAYPROG spray packets
100013 IBM3270PROG IBM 3270 mapper
100014 IBMRJEPROG RJE mapper
100015 SELNSVCPROG selection service
100016 RDATABASEPROG remote database access
100017 REXECPROG remote execution
100018 ALICEPROG Alice Office Automation
100019 SCHEDPROG scheduling service
100020 LOCKPROG local lock manager
100021 NETLOCKPROG network lock manager
100022 X25PROG x.25 inr protocol
100023 STATMON1PROG status monitor 1
100024 STATMON2PROG status monitor 2
100025 SELNLIBPROG selection library
100026 BOOTPARAMPROG boot parameters service
100027 MAZEPROG mazewars game
100028 YPUPDATEPROG NIS update
100029 KEYSERVERPROG key server
100030 SECURECMDPROG secure login
100031 NETFWDIPROG nfs net forwarder init
100032 NETFWDTPROG nfs net forwarder trans
100033 SUNLINKMAP_PROG sunlink MAP
100034 NETMONPROG network monitor
100035 DBASEPROG lightweight database
100036 PWDAUTHPROG password authorisation
100037 TFSPROG translucent file svc
100038 NSEPPROG nse server
100039 NSE_ACTIVATE_PROG nse activate daemon
100043 SHOWHFD showfh
150001 PCNFSDPROG pc password authorisation
200000 PYRAMIDLOCKINGPROG Pyramid locking
200001 PYRAMIDSYS5 Pyramid Sys5
200002 CADDS_IMAGE CV cadds_image
300001 ADT_RFLOCKPROG ADT file locking
20000000 - 3fffffff steht für freie Benutzung
40000000 - 5fffffff vorübergehend besetzt
60000000 - 7fffffff reserviert
80000000 - 9fffffff reserviert
a0000000 - bfffffff reserviert
c0000000 - dfffffff reserviert
e0000000 - ffffffff reserviert
Das Portmapper Protokoll ist in der RPC-Sprache angegeben.
const PMAP_PORT = 111 /* portmapper port number */
/*
** A mapping of (program, version, protocoll) to port number
*/
struct mapping {
unsigned int prog;
unsigned int vers;
unsigned int prot;
unsigned int port;
};
/*
** Supported values for port field
*/
const IPPROTO_TCP = 6;
const IPPROTO_UDP = 17;
/*
** A list of mappings
*/
struct *pmaplist {
mapping map;
pmaplist *next;
};
/*
** Arguments to callit()
*/
struct call_args {
unsigned int prog;
unsigned int vers;
unsigned int proc;
opaque args<>;
};
/*
** Results of callit()
*/
struct call_result {
unsigned int port;
opaque res<>;
};
/*
** Portmapper procedures
*/
program PMAP_PROG {
version PMAP_VERS {
void PMAPPROOC_NULL (void) = 0;
bool PMAPPROOC_SET (mapping) = 1;
bool PMAPPROOC_UNSET (mapping) = 2;
uint PMAPPROOC_GETPORT (mapping) = 3;
pmaplist PMAPPROOC_DUMP (void) = 4;
call_result PMAPPROOC_CALLIT (call_args) = 5;
} = 2;
} = 100000;
Beschreibung der Prozeduren:
PMAPPROOC_NULL: keine Aktion, nur für Testzwecke
PMAPPROOC_SET: Registrierung
PMAPPROOC_UNSET: Macht die Registrierung rückgängig
PMAPPROOC_GETPORT: Gibt die Portnummer zurück (program, version, protokol),
oder 0, wenn nicht registriert.
PMAPPROOC_DUMP: Gibt die Liste aller registrierten Tripel (program,
version, protokol).
PMAPPROOC_CALLIT: Ruft das angesprochene Programm und sendet die
Ergebnisse mit UDP an den Client zurück, wenn
Programm fehlerfrei abgelaufen ist. Wird benutzt
bei Broadcasting.