InterfaceName:
TYPE =
RECORD [
type: LONG STRING ← NIL, -- e.g., "AlpineAccess.Alpine"
instance: LONG STRING ← NIL, -- e.g., "MontBlanc.Alpine"
version: VersionRange ← matchAllVersions ];
defaultInterfaceName: InterfaceName = [];
VersionRange:
TYPE =
MACHINE
DEPENDENT
RECORD[first, last:
CARDINAL];
client-defined, closed interval
matchAllVersions: VersionRange = [1,0];
importer: use any version; exporter: no versioning implied
maxPrincipalLength:
CARDINAL =
MIN[maxShortStringLength, GVBasics.maxRNameLength];
Limit on length of ropes used for Principal names
Principal:
TYPE =
LONG
STRING;
Name of authentication principal
EncryptionKey:
TYPE = GVBasics.Password;
DES key
MakeKey: PROCEDURE [text: LONG STRING] RETURNS[EncryptionKey];
Conversation: TYPE = LONG POINTER TO ConversationObject;
ConversationObject: PRIVATE TYPE;
SecurityLevel:
TYPE =
MACHINE
DEPENDENT {
none(0), -- unauthenticated, insecure; used for "unencrypted"
authOnly(1), -- authenticated, but unencrypted calls
ECB(2), -- authenticated, encrypt with ECB mode of DES
CBC(3), -- authenticated, encrypt with CBC mode of DES
CBCCheck(4) -- authenticated, encrypt with CBC mode of DES + checksum
};
ConversationLevel: TYPE = SecurityLevel[authOnly..CBCCheck];
unencrypted: Conversation =
NIL;
Dummy conversation; may be passed to RPC runtime.
GetConversationID[unencrypted] = ERROR;
GetCaller[unencrypted] = NIL;
GetLevel[unencrypted] = none;
GenerateConversation:
PROC
RETURNS[Conversation];
Returns a handle for a previously unused Conversation. This conversation is only for local use, it must not be passed to the RPC runtime.
GetConversationID[GenerateConversation[]] = unique ID;
GetCaller[GenerateConversation[]] = NIL;
GetLevel[GenerateConversation[]] = "none";
StartConversation:
PROCEDURE[
caller: Principal,
key: EncryptionKey,
callee: Principal,
level: ConversationLevel ]
RETURNS[conversation: Conversation];
Obtains authenticator for conversation, registers it with runtime, and allocates ConversationID
EndConversation:
PROCEDURE [conversation: Conversation];
Terminates use of this conversation
GetCaller:
PROCEDURE [conversation: Conversation]
RETURNS [caller: Principal];
Returns the caller name for a current call. Result is NIL if conversation's security level is "none" (including conversation = "unencrypted").
GetLevel: PROCEDURE [conversation: Conversation] RETURNS [level: SecurityLevel];
ConversationID:
TYPE[3];
UID allocated by initiator host
GetConversationID:
PROC[conversation: Conversation]
RETURNS[id: ConversationID];
Returns permanently unique ID of this conversation
AuthenticateFailure:
TYPE = {
communications, -- couldn't contact authentication server(s) --
badCaller, -- invalid caller name --
badKey, -- incorrect caller password --
badCallee -- invalid callee name --
};
ExportFailure:
TYPE = {
communications, -- couldn't access binding database --
badType, -- unacceptable interface type name --
badInstance, -- unacceptable interface instance name --
badVersion, -- statically silly version range --
tooMany, -- too many exports for local tables --
badCredentials -- not allowed to change the database --
};
ImportFailure:
TYPE = {
communications, -- couldn't access binding database --
badType, -- unacceptable interface type name --
badInstance, -- unacceptable interface instance name --
badVersion, -- statically silly version range --
wrongVersion, -- exported version not in req'd range --
unbound, -- this instance not exported --
stubProtocol -- exporter protocol incompatible with importer --
};
CallFailure:
TYPE = {
timeout, -- no acknowledgement within reasonable time --
unbound, -- server no longer exports the interface --
busy, -- server says it's too busy --
runtimeProtocol, -- user/server runtimes don't understand each other --
stubProtocol -- user/server stubs don't understand each other --
};
AuthenticateFailed:
ERROR[why: AuthenticateFailure];
Raised by StartConversation
ExportFailed:
ERROR[why: ExportFailure];
Raised by ExportInterface
ImportFailed:
ERROR[why: ImportFailure];
Raised by ImportInterface
CallFailed:
SIGNAL[why: CallFailure];
Raised by any remote call; only why=timeout is resumable