-- File: PupRouterCool.Mesa, Last Edit: HGM July 15, 1979 9:35 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, BeSurePupIsOn,
pupRoutingTable, PupRoutingTableEntry,
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;
routing: DESCRIPTOR FOR ARRAY OF PupRoutingTableEntry ← GetPupRoutingTable[];
network: DriverDefs.Network ← NIL;
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;
IF destNet<LENGTH[routing] THEN network ← routing[destNet].network;
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 ← IF network#NIL THEN [network.netNumber] ELSE me.net;
IF remote.host=fillInHostID THEN
remote.host ← IF network#NIL THEN [network.hostNumber] ELSE 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;
GetPupRoutingTable: PROCEDURE RETURNS [
DESCRIPTOR FOR ARRAY OF PupRoutingTableEntry ] =
BEGIN
BeSurePupIsOn[];
RETURN[pupRoutingTable];
END;
GetFirstPupSocket: PROCEDURE RETURNS [PupRouterSocket] =
BEGIN
BeSurePupIsOn[];
RETURN[firstSocket];
END;
GetHopsToNetwork: PROCEDURE [net: PupTypes.PupNetID] RETURNS [CARDINAL] =
BEGIN
routing: DESCRIPTOR FOR ARRAY OF PupRoutingTableEntry ← GetPupRoutingTable[];
BeSurePupIsOn[];
IF net ~IN [0..LENGTH[routing]) THEN RETURN [LAST[CARDINAL]];
RETURN[routing[net].hop];
END;
END.