-- RPC: Internal interface

-- RPCInternal.mesa

-- Andrew Birrell March 10, 1983 12:28 pm

DIRECTORY
BufferDefs  USING[ PupBuffer ],
DESFace   USING[ IV, Key ],
MesaRPC  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

-- ******** Modules for start-up sequence. Main control is RPCPktIO ******** --

RPCBinding: PROGRAM;
RPCSecurity: PROGRAM;
RPCPktStreams: PROGRAM;



-- ******** Binding: exported by RPCBinding ******** --

ExportInstance: TYPE = RECORD[
-- Exporter's record of exported interface --
id: RPCPkt.DispatcherID,
dispatcher: RPCLupine.Dispatcher,
mds: CARDINAL,
name: MesaRPC.InterfaceName,
stubProtocol: MesaRPC.VersionRange ];

ExportTable: TYPE = RECORD[
used: CARDINAL,
entries: SEQUENCE length: RPCPkt.ExportHandle OF ExportInstance];

exportTable: LONG POINTER TO 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: LONG POINTER TO ConversationObject,
id: RPCPkt.ConversationID,
level: MesaRPC.SecurityLevel,
key: DESFace.Key, -- conversation key --
iv: DESFace.IV,
originator: MesaRPC.Principal,
responder: MesaRPC.Principal,
authenticator: LONG DESCRIPTOR FOR ARRAY OF WORD];

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: MesaRPC.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: MesaRPC.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: BufferDefs.PupBuffer,-- incoming packet --
callHeader: LONG POINTER TO RPCPkt.Header, -- encrypted --
callPktID: RPCPkt.PktID-- clear --,
   convHandle: MesaRPC.Conversation]
RETURNS[BOOLEAN];
-- Generates RFA response packet if request matches thisPktID --



-- ******** Packet stream functions: exported by RPCPktStream ******** --

DoSignal: PROC[b: BufferDefs.PupBuffer, pktLength: RPCLupine.DataLength,
signalHandler: RPCLupine.Dispatcher,
  convHandle: MesaRPC.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 --

END.