-- File: PupRouterCool.Mesa, Last Edit: -- HGM July 15, 1979 9:35 PM -- Taft May 10, 1983 2:43 PM -- This section of code is mostly used when creating/destroying sockets -- Copyright Xerox Corporation 1979, 1980 DIRECTORY CommUtilDefs: FROM "CommUtilDefs" USING [InitializeCondition, GetTicks], PupRouterDefs: FROM "PupRouterDefs" USING [ routerLock, maxHop, BeSurePupIsOn, IfMissing, PupRoutingTableEntry, RoutingCacheEntry, GetRoutingCacheEntry, firstSocket, PupRouterSocket], DriverDefs: FROM "DriverDefs" USING [doDebug, Network, GetDeviceChain], PupDefs: FROM "PupDefs", -- EXPORTS BufferDefs: FROM "BufferDefs" USING [QueueInitialize, QueueCleanup], PupTypes: FROM "PupTypes" USING [ fillInNetID, fillInHostID, fillInSocketID, PupAddress, PupNetID, PupSocketID, Pair]; PupRouterCool: MONITOR LOCKS PupRouterDefs.routerLock IMPORTS CommUtilDefs, DriverDefs, PupRouterDefs, BufferDefs EXPORTS PupDefs, PupRouterDefs = PUBLIC BEGIN OPEN PupTypes, PupRouterDefs; spareSocket: CARDINAL ← 1000B; nextConnectionID: CARDINAL ← 1000; UniqueLocalPupSocketID: PUBLIC ENTRY PROCEDURE RETURNS [socket: PupSocketID] = BEGIN IF (spareSocket←spareSocket+1)=0 THEN spareSocket←1000B; socket ← [CommUtilDefs.GetTicks[],spareSocket]; END; UniqueLocalPupAddress: PUBLIC PROCEDURE [him: POINTER TO PupAddress] RETURNS [me: PupAddress] = BEGIN RETURN[GetLocalPupAddress[PupTypes.fillInSocketID,him]]; END; NextPupConnectionID: PUBLIC ENTRY PROCEDURE RETURNS [p: PupTypes.Pair] = BEGIN p.a ← CommUtilDefs.GetTicks[]; p.b ← nextConnectionID ← nextConnectionID+1; END; GetLocalPupAddress: PUBLIC PROCEDURE [local: PupSocketID, remote: POINTER TO PupAddress] RETURNS [me: PupAddress] = BEGIN destNet: CARDINAL ← 0; network: DriverDefs.Network ← NIL; -- Don't get fancy here unless this machine actually has multiple net addresses. -- Aspects of this logic are still moderately buggy.... IF DriverDefs.GetDeviceChain[].next#NIL THEN BEGIN IF remote#NIL THEN BEGIN OPEN PupTypes; destNet ← remote.net; -- Maybe we should scan for the right net if he specifies a host? IF remote.net=fillInNetID OR remote.host=fillInHostID THEN destNet ← 0; END; network ← GetPupRoutingTableEntry[net: [destNet]].network; END; IF network=NIL THEN network ← DriverDefs.GetDeviceChain[]; me.net ← [network.netNumber]; me.host ← [network.hostNumber]; me.socket ← IF local#PupTypes.fillInSocketID THEN local ELSE UniqueLocalPupSocketID[]; IF remote#NIL THEN BEGIN OPEN PupTypes; IF remote.net=fillInNetID THEN remote.net ← me.net; IF remote.host=fillInHostID THEN remote.host ← me.host; IF remote.socket=fillInSocketID THEN remote.socket ← me.socket; END; END; PupRouterKnowAboutSocket: PUBLIC ENTRY PROCEDURE [so: PupRouterSocket] = BEGIN IF DriverDefs.doDebug THEN BeSurePupIsOn[]; CommUtilDefs.InitializeCondition[@so.ready,0]; BufferDefs.QueueInitialize[@so.input]; so.next ← firstSocket; firstSocket ← so; END; PupRouterForgetAboutSocket: PUBLIC ENTRY PROCEDURE [so: PupRouterSocket] = BEGIN previous: PupRouterSocket; IF DriverDefs.doDebug THEN BeSurePupIsOn[]; IF firstSocket=so THEN firstSocket ← so.next ELSE FOR previous←firstSocket,previous.next UNTIL previous=NIL DO IF previous.next=so THEN BEGIN previous.next ← so.next; EXIT; END; ENDLOOP; BufferDefs.QueueCleanup[@so.input]; END; GetFirstPupSocket: PROCEDURE RETURNS [PupRouterSocket] = BEGIN BeSurePupIsOn[]; RETURN[firstSocket]; END; GetHopsToNetwork: PROCEDURE [net: PupTypes.PupNetID] RETURNS [CARDINAL] = BEGIN BeSurePupIsOn[]; RETURN[GetPupRoutingTableEntry[net: net].hop]; END; GetPupRoutingTableEntry: ENTRY PROCEDURE [ net: PupNetID, ifMissing: IfMissing ← probeAndWait, promote: BOOLEAN ← TRUE] RETURNS [PupRoutingTableEntry] = BEGIN rte: POINTER TO RoutingCacheEntry ← GetRoutingCacheEntry[ net: net, ifMissing: ifMissing, promote: promote]; RETURN [IF rte#NIL THEN rte.entry ELSE [hop: maxHop+1, time: 0, route: [0], network: NIL]]; END; END.