DIRECTORY BufferDefs USING[ PupBuffer ], PrincOps USING[ PsbIndex ], PupTypes USING[ PupHostID, PupNetID, PupSocketID ], RPCLupine USING[ DataLength, Dispatcher, RPCPkt ], RPCPrivate USING[ rpcSocket ]; RPCPkt: DEFINITIONS SHARES RPCLupine = BEGIN Header: TYPE = MACHINE DEPENDENT RECORD[ length (0:0..14): [0..77777B], oddByte (0:15..15): { no(0), yes(1) }, type (1): PktType, destPSB (2): PrincOps.PsbIndex,-- field has 6 extra bits srcePSB (3): PrincOps.PsbIndex,-- field has 6 extra bits destHost (4): Machine, destSoc (5): PupTypes.PupSocketID, srceHost (7): Machine, srceSoc (8): PupTypes.PupSocketID, conv (10): PktConversationID, pktID (12): PktID, call (16): SELECT OVERLAID * FROM calling => [ dispatcher (16): DispatcherDetails], responding => [ outcome (16): Outcome, fill (17): ARRAY[SIZE[Outcome]..SIZE[DispatcherDetails]) OF WORD], ENDCASE ]; PktType: TYPE = MACHINE DEPENDENT RECORD[ -- "type" word of a Pup -- transport (0:0..7): [0..255], -- should be zero before sending -- subType (0:8..10): { rpc(3B), (7B) }, eom (0:11..11): { end(0), notEnd(1) }, ack (0:12..12): { dontAck(0), pleaseAck(1) }, class (0:13..15): { call(0), data(1), ack(2), rfa(4), (7) } ]; pktLengthOverhead: RPCLupine.DataLength = SIZE[Header] + 1--checksum--; Machine: TYPE = MACHINE DEPENDENT RECORD[ net: PupTypes.PupNetID, host: PupTypes.PupHostID ]; HostConversationID: TYPE = MACHINE DEPENDENT RECORD[ ls(0): CARDINAL, ms(1): [0..77777B] ]; ConversationID: TYPE = RECORD[ originator: Machine, count: HostConversationID]; PktConversationID: TYPE = MACHINE DEPENDENT RECORD[ ls(0): CARDINAL, originator(1:0..0): { caller, callee }, ms(1:1..15): [0..77777B] ]; ConnectionID: TYPE = MACHINE DEPENDENT RECORD[ conv(0): PktConversationID, caller(2): Machine, activity(3): PrincOps.PsbIndex ]; CallCount: TYPE = LONG CARDINAL; PktID: TYPE = MACHINE DEPENDENT RECORD[ activity(0): PrincOps.PsbIndex,-- field has 6 extra bits-- callSeq(1): CallCount, pktSeq(3): CARDINAL ]; Outcome: TYPE = MACHINE DEPENDENT { -- possible responses to call or signal -- result(0), -- normal -- unbound(1), -- dispatcher not known -- signal(2), -- signal propagation -- unwind(3), -- signal is unwinding -- protocol(4), -- stub protocol error detected -- (LAST[CARDINAL]) -- room for expansion? -- }; DispatcherDetails: TYPE = MACHINE DEPENDENT RECORD[ mds: CARDINAL, -- top half of dispatcher's MDS base address -- dispatcherID: DispatcherID, -- exporter-relative UID of interface instance -- dispatcherHint: ExportHandle -- hint to exporter host's export table -- ]; DispatcherID: TYPE = LONG CARDINAL; noDispatcher: DispatcherID = 0; ExportHandle: TYPE = CARDINAL; SetupResponse: PROC[header: LONG POINTER TO Header] = INLINE BEGIN header.destHost _ header.srceHost; header.destSoc _ RPCPrivate.rpcSocket; 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]; IdleReceive: PROC[pkt: RPCLupine.RPCPkt, maxlength: CARDINAL]; EnqueueAgain: PROC[b: BufferDefs.PupBuffer]; END. ÎRPC: layout of packets RPCPkt.mesa Andrew Birrell September 7, 1983 3:34 pm ******** Layout of stub-packets ******** end of standard Pup header For secure conversations, the remainder of the packet must be encrypted Mapping from Pup pkt types to RPC pkt types: 140B = [end, dontAck, call ] 141B = [end, dontAck, data ] 142B = [, dontAck, ack ] (also 162B) 143B = unused (also 163B) 144B = [, dontAck, rfa ] (also 164B) 150B = [end, pleaseAck, call ] 151B = [end, pleaseAck, data ] 152B = [, pleaseAck, ack ] (also 172B) 153B = unused (also 173B) 154B = [, pleaseAck, rfa ] (also 174B) 160B = [notEnd, dontAck, call ] 161B = [notEnd, dontAck, data ] 170B = [notEnd, pleaseAck, call ] 171B = [notEnd, pleaseAck, data ] Difference between RPCLupine.DataLength and transmitted Pup length for unencrypted packets Unambiguous name of a host Host-relative ID of a conversation; unique for all time Absolute ID of a conversation; unique for all hosts and all time Same as ConversationID, but abbreviated for within a packet. Assumes originator is always caller or callee Uniquely identifies an independent sequence of calls [ConnectionID,CallCount] uniquely identifies call for all hosts and time [ConversationID,PktID] uniquely identifies pkt for all hosts and time. ******** Single-packet communication: exported by RPCPktIO ******** Reliable transmission of given packet, and receipt of next packet; "newLength" is data length of incoming packet, if any. Returns when new packet arrives; "maxlength" is number of words in the pkt buffer starting from pkt.header (total, including all overheads) Dispatches packet to appropriate process; used by idler processes to requeue pkt that had incorrect destPSB. ÊΘJšœ™Jšœ ™ Jšœ)™)J˜šÏk ˜ Jšœ œ˜Jšœ œ ˜Jšœ œ%˜3Jšœ œ#˜2Jšœ œ˜—J˜šœ ˜Jšœ ˜—J˜Jš˜J˜Jšœ(™(˜š œœœ œœ˜(J˜J˜&J˜Jšœ œ Ïc˜8Jšœ œ ž˜8J˜J˜"J˜J˜"Jšœ™J˜JšœG™GJ˜šœ œœ˜!˜ J˜$—˜J˜Jš œ œœ œœœ˜B—Jšœ˜ ——J˜š œ œœ œœž˜FJšœž#˜AJ˜%J˜&J˜-J˜>—J˜šœ,™,Jšœ™Jšœ™Jšœ'™'Jšœ!™!Jšœ'™'Jšœ™Jšœ™Jšœ(™(Jšœ!™!Jšœ(™(Jšœ ™ Jšœ ™ Jšœ!™!Jšœ!™!—J˜šœ*œ ž œ˜GJšœBž™Z—J˜š œ œœ œœ˜)Jšœ™J˜J˜—J˜š œœœ œœ˜4Jšœ7™7Jšœœ˜J˜—J˜šœœœ˜Jšœ@™@J˜J˜—J˜š œœœ œœ˜3Jšœk™kJšœœ˜J˜'J˜—J˜š œœœ œœ˜.Jšœ4™4J˜J˜Jšœ!˜!—J˜šœ œœœ˜ JšœH™H—J˜š œœœ œœ˜'JšœF™FJšœ œ ž˜:J˜Jšœ œ˜—J˜šœ œœ œž*˜NJšœ ž œ˜Jšœ ž˜&Jšœ ž˜#Jšœ ž˜$Jšœ ž"˜/Jšœœœž˜*J˜—J˜š œœœ œœ˜3Jšœœž/˜>Jšœž1˜MJšœž*œ˜J—J˜Jšœœœœ˜#J˜J˜J˜Jšœœœ˜J˜š Ïn œœ œœœ ˜JšœFžE™‹—J˜šŸ œœ˜,Jšœm™m—J˜—Jšœ˜J˜—…— ä€