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. 8RPCPkt.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. RPC: layout of packets Andrew Birrell September 7, 1983 3:34 pm Bob Hagmann February 8, 1985 3:32:26 pm PST ******** 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. Κι˜headšœ ™ Icodešœ Οmœ1™<—šœ™Jšœ)™)L™+—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˜—…— δ