RPCInternal.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
RPC: Internal interface
Andrew Birrell September 7, 1983 4:12 pm
Bob Hagmann February 8, 1985 3:33:38 pm PST
Hal Murray, May 12, 1986 11:56:13 am PDT
DIRECTORY
PupBuffer USING [Buffer],
DESFace USING [Block, IV, Key],
PupWKS USING [rpc],
RPC USING [Conversation, InterfaceName, Principal, SecurityLevel, VersionRange],
RPCLupine USING [DataLength, Dispatcher, RPCPkt],
RPCPkt USING [CallCount, ConnectionID, ConversationID, DispatcherDetails, DispatcherID, ExportHandle, Header, PktConversationID, PktID, Machine];
RPCInternal: DEFINITIONS =
BEGIN
******** Start-up sequence. Main control is RPCPktIO ********
StartRPCBinding: PROC [RPCPkt.Machine];
StartRPCSecurity: PROC [RPCPkt.Machine];
StartRPCPktStreams: PROC [RPCPkt.Machine];
RollbackRPCBinding: PROC;
RollbackRPCSecurity: PROC;
RollbackRPCPktStreams: PROC;
******** Binding: exported by RPCBinding ********
ExportInstance: TYPE = RECORD[
Exporter's record of exported interface
id: RPCPkt.DispatcherID,
dispatcher: RPCLupine.Dispatcher,
name: RPC.InterfaceName,
stubProtocol: RPC.VersionRange ];
ExportTable: TYPE = RECORD[
used: CARDINAL,
entries: SEQUENCE length: RPCPkt.ExportHandle OF ExportInstance];
exportTable: REF ExportTable;
ImportInstance: TYPE = RECORD[
Importer's record of successful binding
host: RPCPkt.Machine,
dispatcher: RPCPkt.DispatcherDetails ];
******** Authentication/Security: exported by RPCSecurity ********
ConversationObject: TYPE = RECORD[
next: REF ConversationObject,
id: RPCPkt.ConversationID,
level: RPC.SecurityLevel,
key: DESFace.Key, -- conversation key --
iv: DESFace.IV,
originator: RPC.Principal,
responder: RPC.Principal,
authenticator: Authenticator];
Authenticator: TYPE = REF AuthenticatorObject;
AuthenticatorObject: TYPE = RECORD[
Allocated storage for an authenticator. For A talking to B using key CK, contains: {KY}KB, spare, { {CK}KB, spare, time, A }KY . The keys are single cipher blocks. The rest is encrypted with CBC-check using a zero IV
SEQUENCE nBlks: CARDINAL OF DESFace.Block ];
firstConversation: RPCPkt.PktConversationID; -- for unencrypted conversations --
EncryptPkt: PROC[pkt: RPCLupine.RPCPkt, l: RPCLupine.DataLength]
RETURNS[CARDINAL];
Encrypts packet using pkt.convHandle; "l" is data length of pkt; returns Pup length of packet.
DecryptPkt: PROC[header: LONG POINTER TO RPCPkt.Header,
convHandle: RPC.Conversation]
RETURNS[ok: BOOLEAN, l: RPCLupine.DataLength];
Decrypts packet using pkt.convHandle; ok iff checksum matches; returns data length of packet
GetConnectionState: PROC[ decrypted: BOOLEAN, callPkt: RPCLupine.RPCPkt]
RETURNS[ ok: BOOLEAN,
id: RPCPkt.ConnectionID,
call: RPCPkt.CallCount,
conv: RPC.Conversation,
l: RPCLupine.DataLength ];
On entry, packet is decrypted iff "decrypted". On exit, packet is decrypted if "ok". If "ok" and not "decrypted", returns pkt data length in "l". Sends RFA and accepts response; results valid iff "ok"
ReplyToRFA: PROC [b: PupBuffer.Buffer,-- incoming packet --
callHeader: LONG POINTER TO RPCPkt.Header, -- encrypted --
callPktID: RPCPkt.PktID-- clear --,
convHandle: RPC.Conversation]
RETURNS[BOOLEAN];
Generates RFA response packet if request matches thisPktID
******** Packet stream functions: exported by RPCPktStream ********
DoSignal: PROC [b: PupBuffer.Buffer, pktLength: RPCLupine.DataLength,
signalHandler: RPCLupine.Dispatcher,
convHandle: RPC.Conversation]
RETURNS[resumePkt: RPCLupine.RPCPkt,
resumeLength: RPCLupine.DataLength,
myLocalFrame: POINTER];
Called from inside PktExchange to handle signal-back packets
ServerMain: PROCEDURE;
FORK'ed when needed by RPCPktIO, to maintain an adequate stock of them
******** For some Voice kludgery that I don't understand /HGM, Jan 86 ********
CopyPrincipal: PROC [from: RPC.Principal, to: LONG POINTER];
EntryGenerate: PROC [ level: RPC.SecurityLevel, iv: DESFace.IV, originator, responder: RPC.Principal, convKey: DESFace.Key, auth: RPCInternal.Authenticator]
RETURNS [ conversation: REF RPCInternal.ConversationObject ];
AddToExportTable: PROC [interface: RPC.InterfaceName, dispatcher: RPCLupine.Dispatcher, stubProtocol: RPC.VersionRange] RETURNS [ instance: RPCPkt.ExportHandle ];
******** For new Communication package /HGM, Jan 86 ********
AllocBuffer: PROC RETURNS [b: PupBuffer.Buffer];
GiveBackBuffer: PROC [b: PupBuffer.Buffer];
SendBuffer: PROC [b: PupBuffer.Buffer];
******** Moved from RPCPkt /HGM, Apr 86 ********
pktLengthOverhead: RPCLupine.DataLength = SIZE[RPCPkt.Header] + 1--checksum--;
Difference between RPCLupine.DataLength and transmitted Pup length for unencrypted packets
SetupResponse: PROC [header: LONG POINTER TO RPCPkt.Header] = INLINE
BEGIN
header.destHost ← header.srceHost;
header.destSoc ← PupWKS.rpc;
header.destPSB ← header.srcePSB;
header.outcome ← result;
END;
PktExchangeState: TYPE = { receiving, sending, call, endCall, authReq };
PktExchange: PROC[inPkt: RPCLupine.RPCPkt, length: RPCLupine.DataLength,
maxlength: RPCLupine.DataLength,
state: PktExchangeState,
signalHandler: RPCLupine.Dispatcher ← NIL]
RETURNS[newPkt: BOOLEAN, newLength: RPCLupine.DataLength];
Reliable transmission of given packet, and receipt of next packet; "newLength" is data length of incoming packet, if any.
IdleReceive: PROC[pkt: RPCLupine.RPCPkt, maxlength: CARDINAL];
Returns when new packet arrives; "maxlength" is number of words in the pkt buffer starting from pkt.header (total, including all overheads)
EnqueueAgain: PROC [b: PupBuffer.Buffer];
Dispatches packet to appropriate process; used by idler processes to requeue pkt that had incorrect destPSB.
END.