<> <> <> DIRECTORY BufferDefs USING [BufferAccessHandle, FreeBufferPool, MakeBufferPool, OisBuffer], Checksums USING [IncrOisTransportControlAndUpdateChecksum, SetChecksum], CommunicationInternal USING [], CommFlags USING [doDebug, doStats], DriverDefs USING [ChangeNumberOfInputBuffers, GetDeviceChain, GetInputBuffer, MaybeGetFreeOisBuffer, Glitch, Network, PutOnGlobalDoneQueue], OISCP USING [allHostIDs, GetFreeSendOisBufferFromPool, SetOisPacketTextLength, unknownHostID, unknownNetID], OISCPConstants USING [routingInformationSocket], OISCPTypes USING [bytesPerPktHeader, maxBytesPerPkt, RoutingInfoTuple, RoutingInfoType, TransPortControl], Process USING [Detach, MsecToTicks, SetTimeout], Router USING [BroadcastThisPacket, checkIt, FindMyHostID, routersFunction, Nibble, primaryMDS, RoutingTableEntry, RoutingTableObject, SendErrorPacket, SendPacket, XmitStatus], StatsDefs USING [StatIncr], SpecialCommunication USING [RoutersFunction], NSAddress USING [broadcastHostNumber, HostNumber, NetworkAddress, NetworkNumber, nullNetworkNumber]; RoutingTableImpl: MONITOR IMPORTS BufferDefs, Checksums, DriverDefs, OISCP, Process, Router, StatsDefs EXPORTS BufferDefs, CommunicationInternal, Router, SpecialCommunication SHARES BufferDefs = BEGIN OPEN OISCP, Router, StatsDefs, SpecialCommunication; <> Network: PUBLIC TYPE = DriverDefs.Network; <> <> <> <> myHostID: NSAddress.HostNumber; -- host ID of this system element <> <> <> routingTableHead: RoutingTableEntry _ NIL; routingTableSize: CARDINAL _ 0; maxRoutingTableSize: CARDINAL = 50; probeAnInternetRouterCounter: CARDINAL; -- keeps track of num of detached processes initialTransportControl: OISCPTypes.TransPortControl = [trace: FALSE, filler: 0, hopCount: 0]; oneHop: Nibble = 1; -- delay to local network is assumd to be one router hop. updateCycles: Nibble = 4; -- timeUnits gets reset to this; number of routing table update cycles. alternatePathTimeUnitThreshHold: CARDINAL = 3; -- we look for alternate routing path if timeUnits fall BELOW this value. maxRouterDelay: CARDINAL = 15; -- max number of router hops maxInternetrouterHops: CARDINAL = 15; -- max number of internetrouter hops <> inrBufferCount: CARDINAL _ 20; -- the number of buffers allocated by an INR. inrRunning, iNRpleaseStop, pleaseStop: BOOLEAN; -- switch to tell the processes to stop routingTableUpdateTimer, responseFromInternetRouter, internetRouterTimer: CONDITION; routingTableFork, internetRouterServerFork: PROCESS; <> RoutingTableScrambled: PUBLIC ERROR = CODE; routingTableSanityChecking: BOOLEAN = FALSE; <> <> <> SanityCheck: PROCEDURE = INLINE BEGIN e: RoutingTableEntry _ routingTableHead; WHILE e#NIL DO IF e.delay=0 THEN ERROR; e _ e.next; ENDLOOP; END; <> <> FindNetworkNumber: PROCEDURE [num: NSAddress.NetworkNumber, advanceEntry: BOOLEAN _ TRUE] RETURNS [e: RoutingTableEntry] = BEGIN prev: RoutingTableEntry _ e _ routingTableHead; UNTIL e=NIL DO IF e.destNetwork=num THEN BEGIN IF advanceEntry AND (prev#routingTableHead) THEN BEGIN prev.next _ e.next; e.next _ routingTableHead; routingTableHead _ e; END; RETURN; END; prev _ e; e _ e.next; ENDLOOP; END; <> <> FindNetwork: PROCEDURE [net: Network] RETURNS [e: RoutingTableEntry] = BEGIN prev: RoutingTableEntry _ e _ routingTableHead; UNTIL e=NIL DO IF e.network=net THEN BEGIN IF prev#routingTableHead THEN BEGIN prev.next _ e.next; e.next _ routingTableHead; routingTableHead _ e; END; RETURN; END; prev _ e; e _ e.next; ENDLOOP; END; <> <> RemoveEntry: PROCEDURE [e: RoutingTableEntry] = BEGIN prev: RoutingTableEntry _ NIL; temp: RoutingTableEntry _ routingTableHead; UNTIL (temp = NIL) OR (temp = e) DO prev _ temp; temp _ temp.next; ENDLOOP; IF CommFlags.doDebug AND (temp = NIL) THEN DriverDefs.Glitch[RoutingTableScrambled]; IF prev = NIL THEN routingTableHead _ e.next ELSE BEGIN IF CommFlags.doDebug AND (prev.next # e) THEN DriverDefs.Glitch[RoutingTableScrambled]; IF CommFlags.doDebug AND (prev.next = NIL) THEN DriverDefs.Glitch[RoutingTableScrambled]; prev.next _ e.next; END; e.next _ NIL; routingTableSize _ routingTableSize - 1; IF CommFlags.doDebug AND routingTableSize>maxRoutingTableSize THEN DriverDefs.Glitch[RoutingTableScrambled]; END; <> AddEntry: PROCEDURE [e: RoutingTableEntry] = BEGIN e.next _ routingTableHead; routingTableHead _ e; routingTableSize _ routingTableSize + 1; IF CommFlags.doDebug AND routingTableSize>maxRoutingTableSize THEN DriverDefs.Glitch[RoutingTableScrambled]; END; EnumerateRoutingTable: PUBLIC ENTRY PROCEDURE [ proc: PROCEDURE [RoutingTableEntry]] = BEGIN e: RoutingTableEntry _ routingTableHead; WHILE (e # NIL) DO proc[e]; e _ e.next; ENDLOOP; END; -- EnumerateRoutingTable RoutingTableCacheFault: PROCEDURE [destNetNumber: NSAddress.NetworkNumber] = BEGIN b: BufferDefs.OisBuffer; e: RoutingTableEntry _ NEW[RoutingTableObject]; e^ _ RoutingTableObject[ next: , destNetwork: destNetNumber, delay: maxRouterDelay, timeUnits: updateCycles, route: unknownHostID, network: NIL]; AddEntry[e]; IF routingTableSanityChecking THEN SanityCheck[]; IF (b _ LOOPHOLE[DriverDefs.GetInputBuffer[TRUE], BufferDefs.OisBuffer])=NIL THEN RETURN; <> <> b.type _ ois; b.ois.transCntlAndPktTp _ [initialTransportControl, routingInformation]; SetOisPacketTextLength[b, 2]; -- just one word of data b.ois.routingType _ routingInfoRequest; Router.BroadcastThisPacket[b]; END; -- RoutingTableCacheFault <> <> <> <> FindNetworkAndTransmit: PUBLIC ENTRY PROCEDURE [b: BufferDefs.OisBuffer] RETURNS [stat: XmitStatus] = BEGIN ENABLE UNWIND => NULL; destHost: NSAddress.HostNumber _ b.ois.destination.host; nextHost: NSAddress.HostNumber; destNetNumber: NSAddress.NetworkNumber; network: Network; e: RoutingTableEntry _ FindNetworkNumber[destNetNumber _ b.ois.destination.net]; IF e=NIL OR (network_e.network)=NIL THEN BEGIN -- outgoing packet for unknown net, <> b.status _ LOOPHOLE[stat _ XmitStatus[noRouteToNetwork]]; DriverDefs.PutOnGlobalDoneQueue[b]; IF e=NIL THEN RoutingTableCacheFault[destNetNumber]; IF CommFlags.doStats THEN StatIncr[statOisSentNowhere]; RETURN; END; <> IF (nextHost _ e.route) = unknownHostID THEN nextHost _ destHost; -- intranet b.status _ LOOPHOLE[stat _ XmitStatus[goodCompletion]]; network.encapsulateOis[b, nextHost]; <> network.sendBuffer[b]; END; -- FindNetworkAndTransmit ForwardPacket: PUBLIC PROCEDURE [b: BufferDefs.OisBuffer] = BEGIN ENABLE UNWIND => NULL; nextHost: NSAddress.HostNumber; e: RoutingTableEntry; network: Network; NotFoundDestinationNetworkLocked: ENTRY PROCEDURE RETURNS [BOOLEAN] = INLINE {RETURN[(e _ FindNetworkNumber[b.ois.destination.net])=NIL OR (network _ e.network)=NIL]}; <> IF b.ois.transCntlAndPktTp.transportControl.hopCount >= maxInternetrouterHops THEN BEGIN Router.SendErrorPacket[b, excessHopsOisErrorCode, 0]; <> DriverDefs.PutOnGlobalDoneQueue[b]; IF CommFlags.doStats THEN StatsDefs.StatIncr[statOisNotForwarded]; RETURN; END; IF NotFoundDestinationNetworkLocked[] THEN BEGIN -- outgoing packet for unknown net Router.SendErrorPacket[b, cantGetThereOisErrorCode, 0]; IF CommFlags.doStats THEN StatIncr[statOisNotForwarded]; b.status _ LOOPHOLE[XmitStatus[noRouteToNetwork]]; <> DriverDefs.PutOnGlobalDoneQueue[b]; END ELSE BEGIN -- outgoing packet Checksums.IncrOisTransportControlAndUpdateChecksum[b]; <> IF (nextHost _ e.route) = unknownHostID THEN nextHost _ b.ois.destination.host; <> network.encapsulateOis[b, nextHost]; network.sendBuffer[b]; IF CommFlags.doStats THEN StatIncr[statOisForwarded]; END; END; -- ForwardPacket <> <> AddNetwork: PUBLIC ENTRY PROCEDURE [newNetwork: Network] = BEGIN AddNetworkLocked[newNetwork]; END; -- AddNetwork <> AddNetworkLocked: PRIVATE PROCEDURE [newNetwork: Network] = BEGIN unknownNetIdEntry, e: RoutingTableEntry; IF NOT newNetwork.alive THEN RETURN; <> e _ FindNetworkNumber[newNetwork.netNumber, FALSE]; <> IF e = NIL THEN BEGIN e _ NEW[RoutingTableObject]; AddEntry[e]; IF newNetwork.netNumber = unknownNetID THEN BEGIN probeAnInternetRouterCounter _ probeAnInternetRouterCounter + 1; Process.Detach[FORK ProbeAnInternetRouter[newNetwork]]; <> END; -- of null network number non-existant END; -- of entry not found e^ _ RoutingTableObject[ next: e.next, destNetwork: newNetwork.netNumber, delay: oneHop, timeUnits: updateCycles, route: unknownHostID, network: newNetwork]; IF routingTableSanityChecking THEN SanityCheck[]; <> <> IF FindNetworkNumber[unknownNetID, FALSE]=NIL THEN BEGIN unknownNetIdEntry _ NEW[RoutingTableObject]; unknownNetIdEntry^ _ RoutingTableObject[ next:, destNetwork: unknownNetID, delay: oneHop, timeUnits: updateCycles, route: unknownHostID, network: newNetwork]; AddEntry[unknownNetIdEntry]; END; END; -- AddNetworkLocked <> RemoveNetwork: PUBLIC ENTRY PROCEDURE [oldNetwork: Network] = BEGIN unknownNetwork: Network; RemoveNetworkLocked[oldNetwork]; <> IF FindNetworkNumber[unknownNetID, FALSE]=NIL AND (unknownNetwork _ DriverDefs.GetDeviceChain[])#NIL THEN AddNetworkLocked[unknownNetwork]; END; -- RemoveNetwork <> RemoveNetworkLocked: PRIVATE PROCEDURE [oldNetwork: Network] = BEGIN e: RoutingTableEntry; DO IF (e _ FindNetwork[oldNetwork])=NIL THEN EXIT; RemoveEntry[e]; <> ENDLOOP; END; -- RemoveNetworkLocked StateChanged: PUBLIC ENTRY PROCEDURE [network: Network] = BEGIN unknownNetwork: Network; RemoveNetworkLocked[network]; AddNetworkLocked[network]; <> <> IF FindNetworkNumber[unknownNetID, FALSE]=NIL AND (unknownNetwork _ DriverDefs.GetDeviceChain[])#NIL THEN AddNetworkLocked[unknownNetwork]; IF routingTableSanityChecking THEN SanityCheck[]; END; -- StateChanged RoutingInformationPacket: PUBLIC ENTRY PROCEDURE [b: BufferDefs.OisBuffer] = BEGIN newDelay: INTEGER; objectNetID: NSAddress.NetworkNumber; sameRoute, betterDelay, awfulDelay, newNetwork: BOOLEAN; localRouterDelay: INTEGER = 1; newRoute: NSAddress.HostNumber = b.ois.source.host; e: RoutingTableEntry; <> <> <> incomingNetwork: Network = b.network; routingPacketType: OISCPTypes.RoutingInfoType = b.ois.routingType; routingInfoLength: CARDINAL = b.ois.pktLength - OISCPTypes.bytesPerPktHeader - 2; -- first word routingInfo: LONG POINTER TO OISCPTypes.RoutingInfoTuple _ @b.ois.routingTuple[0]; UpdateUnnumberedNetTable: INTERNAL PROCEDURE = BEGIN IF incomingNetwork.netNumber # unknownNetID THEN RETURN; incomingNetwork.netNumber _ b.ois.source.net; AddNetworkLocked[incomingNetwork]; END; -- UpdateUnnumberedNetTable UpdateRoutingTable: INTERNAL PROCEDURE = BEGIN changed: BOOLEAN _ FALSE; THROUGH [0..routingInfoLength/(2*SIZE[OISCPTypes.RoutingInfoTuple])) DO newDelay _ routingInfo.interrouterDelay + localRouterDelay; awfulDelay _ newDelay > maxRouterDelay; objectNetID _ routingInfo.objectNetID; routingInfo _ routingInfo + SIZE[OISCPTypes.RoutingInfoTuple]; IF newDelay = oneHop THEN LOOP; IF (e _ FindNetworkNumber[objectNetID, FALSE])=NIL THEN IF (routersFunction=vanillaRouting) OR awfulDelay THEN LOOP ELSE -- INR - keeps a large table of info that doesn't have an awful delay BEGIN e _ NEW[RoutingTableObject]; e^ _ [next: , destNetwork: objectNetID, delay: newDelay, timeUnits: updateCycles, route: newRoute, network: incomingNetwork]; AddEntry[e]; changed _ TRUE; END; sameRoute _ e.route = newRoute AND e.network = incomingNetwork; betterDelay _ newDelay < e.delay; newNetwork _ (e.timeUnits < alternatePathTimeUnitThreshHold) OR (e.network = NIL); <> IF sameRoute THEN BEGIN IF awfulDelay THEN BEGIN <> <> newDelay _ maxRouterDelay; END ELSE BEGIN e.timeUnits _ updateCycles; END; IF e.delay#newDelay THEN changed _ TRUE; e.delay _ newDelay; END ELSE IF (newNetwork AND NOT awfulDelay) OR (NOT newNetwork AND betterDelay) THEN BEGIN changed _ TRUE; e^ _ RoutingTableObject[ next: e.next, destNetwork: objectNetID, delay: newDelay, timeUnits: updateCycles, route: newRoute, network: incomingNetwork]; END; ENDLOOP; <> IF routersFunction=interNetworkRouting AND changed THEN NOTIFY internetRouterTimer; END; -- UpdateRoutingTabler <
> IF routingTableSanityChecking THEN SanityCheck[]; IF b.ois.transCntlAndPktTp.packetType # routingInformation OR (b.ois.source.host=myHostID AND routingPacketType=routingInfoResponse) -- don't need to listen to myself OR newRoute = unknownHostID OR incomingNetwork = NIL THEN RETURN; IF CommFlags.doStats THEN StatIncr[statOisGatewayPacketsRecv]; IF routersFunction = interNetworkRouting AND routingPacketType = routingInfoRequest THEN BEGIN e: RoutingTableEntry; netNumber: NSAddress.NetworkNumber = b.ois.source.net; net: Network _ incomingNetwork; host: NSAddress.HostNumber _ b.ois.source.host; <> IF netNumber#unknownNetID THEN BEGIN e _ FindNetworkNumber[netNumber, FALSE]; IF e=NIL OR (net_e.network)=NIL THEN RETURN; -- can't find route back to requestor IF e.route#unknownHostID THEN host _ e.route; END; SendRoutingInfoResponse[b.ois.source, host, net]; RETURN; END; IF routingPacketType = routingInfoResponse THEN BEGIN <> UpdateUnnumberedNetTable[]; UpdateRoutingTable[]; END; IF routingTableSanityChecking THEN SanityCheck; END; -- RoutingInformationPacket <> <> <> <> <> <> ProbeAnInternetRouter: PROCEDURE [network: Network] = BEGIN myBufferAccessHandle: BufferDefs.BufferAccessHandle _ BufferDefs.MakeBufferPool[total: 1, send: 1, forSystemUse: FALSE]; b: BufferDefs.OisBuffer; ExitFromProbeAnInternetRouter: ENTRY PROCEDURE = INLINE BEGIN WHILE myBufferAccessHandle.sendInUse#0 DO -- wait for all async sends to complete WAIT responseFromInternetRouter; ENDLOOP; probeAnInternetRouterCounter _ probeAnInternetRouterCounter - 1; BROADCAST responseFromInternetRouter END; ResponseFromInternetRouterPositive: ENTRY PROCEDURE RETURNS [BOOLEAN] = INLINE BEGIN WAIT responseFromInternetRouter; RETURN[network.netNumber # unknownNetID]; END; -- ResponseFromInternetRouterPositive THROUGH [0..30) UNTIL pleaseStop DO b _ OISCP.GetFreeSendOisBufferFromPool[myBufferAccessHandle]; b.ois.transCntlAndPktTp _ [initialTransportControl, routingInformation]; SetOisPacketTextLength[b, 2]; -- just one word of data b.ois.source _ b.ois.destination _ [net: unknownNetID, host: allHostIDs, socket: OISCPConstants.routingInformationSocket]; b.ois.source.host _ myHostID; b.ois.routingType _ routingInfoRequest; Router.SendPacket[b]; IF CommFlags.doStats THEN StatsDefs.StatIncr[statOisBroadcast]; IF ResponseFromInternetRouterPositive[] THEN EXIT; ENDLOOP; ExitFromProbeAnInternetRouter[]; BufferDefs.FreeBufferPool[myBufferAccessHandle]; END; -- ProbeAnInternetRouter <> <> <> <> <> <<'to' is the ultimate destination, 'host' is the encapsulation destination.>> SendRoutingInfoResponse: PROCEDURE [to: NSAddress.NetworkAddress, host: NSAddress.HostNumber, network: Network] = BEGIN maxBytesPerRoutingPacket: CARDINAL = OISCPTypes.maxBytesPerPkt - 2*SIZE[OISCPTypes.RoutingInfoTuple]; nextRoutingEntry: RoutingTableEntry _ routingTableHead; sendBuf: BufferDefs.OisBuffer _ NIL; nextResponseEntry: INTEGER; IF routingTableSanityChecking THEN SanityCheck[]; UNTIL nextRoutingEntry=NIL DO IF nextRoutingEntry.destNetwork # NSAddress.nullNetworkNumber AND nextRoutingEntry.network # NIL THEN -- bypass the null network entry or a nil entry BEGIN IF sendBuf=NIL THEN BEGIN IF (sendBuf _ DriverDefs.MaybeGetFreeOisBuffer[])=NIL THEN RETURN; -- give up! sendBuf.ois.transCntlAndPktTp _ [initialTransportControl, routingInformation]; sendBuf.ois.routingType _ routingInfoResponse; sendBuf.ois.source _ [network.netNumber, myHostID, OISCPConstants.routingInformationSocket]; sendBuf.ois.destination _ to; sendBuf.ois.pktLength _ OISCPTypes.bytesPerPktHeader + 2; sendBuf.network _ network; sendBuf.allNets _ (host = NSAddress.broadcastHostNumber); nextResponseEntry _ 0; END; -- of getting a new send buffer sendBuf.ois.routingTuple[nextResponseEntry] _ [nextRoutingEntry.destNetwork, nextRoutingEntry.delay]; nextResponseEntry _ nextResponseEntry + 1; sendBuf.ois.pktLength _ sendBuf.ois.pktLength+2*SIZE[OISCPTypes.RoutingInfoTuple]; END; nextRoutingEntry _ nextRoutingEntry.next; IF (sendBuf#NIL) AND ((nextRoutingEntry=NIL) OR (sendBuf.ois.pktLength>=maxBytesPerRoutingPacket)) THEN BEGIN IF ~network.alive THEN BEGIN DriverDefs.PutOnGlobalDoneQueue[sendBuf]; END ELSE BEGIN IF checkIt THEN Checksums.SetChecksum[sendBuf] ELSE sendBuf.ois.checksum _ 177777B; network.encapsulateOis[sendBuf, host]; network.sendBuffer[sendBuf]; END; sendBuf _ NIL; END; -- of sending a full routing buffer ENDLOOP; -- end of send loop END; -- SendRoutingInfoResponse <> <<- Protocol Response packets gratuitously, if this system element is an internet router.>> InternetRouterServer: ENTRY PROCEDURE = BEGIN inrAccessHandle: BufferDefs.BufferAccessHandle; inrRunning _ TRUE; inrAccessHandle _ BufferDefs.MakeBufferPool[inrBufferCount, 0, 0, 0, TRUE]; <> <> DriverDefs.ChangeNumberOfInputBuffers[TRUE]; UNTIL pleaseStop OR iNRpleaseStop DO WAIT internetRouterTimer; IF pleaseStop OR iNRpleaseStop THEN EXIT; SendRoutingInfoResponse[[unknownNetID, NSAddress.broadcastHostNumber, OISCPConstants.routingInformationSocket], NSAddress.broadcastHostNumber, DriverDefs.GetDeviceChain[]]; ENDLOOP; <> DriverDefs.ChangeNumberOfInputBuffers[FALSE]; BufferDefs.FreeBufferPool[inrAccessHandle]; inrRunning _ FALSE; END; -- InternetRouterServer <> <> <> RoutingTableUpdater: ENTRY PROCEDURE = BEGIN rte: RoutingTableEntry; UNTIL pleaseStop DO IF routingTableSanityChecking THEN SanityCheck[]; <> rte _ routingTableHead; WHILE (rte # NIL) DO IF rte.delay # oneHop THEN BEGIN IF rte.timeUnits = 0 THEN BEGIN temp: RoutingTableEntry _ rte; rte _ rte.next; RemoveEntry[temp]; <> LOOP; END ELSE rte.timeUnits _ rte.timeUnits - 1; END; rte _ rte.next; ENDLOOP; WAIT routingTableUpdateTimer; ENDLOOP; END; -- RoutingTableUpdater <> <> FindDestinationRelativeNetID: PUBLIC ENTRY PROCEDURE [destNet: NSAddress.NetworkNumber] RETURNS [netNumber: NSAddress.NetworkNumber] = BEGIN e: RoutingTableEntry; IF (e _ FindNetworkNumber[destNet])=NIL OR (e.network=NIL) THEN RETURN[unknownNetID]; netNumber _ e.network.netNumber; IF netNumber=unknownNetID THEN BEGIN <> <> n: Network _ DriverDefs.GetDeviceChain[]; DO IF (netNumber _ n.netNumber)#unknownNetID THEN EXIT; -- gotIt! IF (n _ n.next)=NIL THEN EXIT; -- a non - unknownNetID network does not exist! ENDLOOP; END; -- find non - unknownNetID network clause END; -- FindDestinationRelativeNetID <> GetRouterFunction: PUBLIC ENTRY PROCEDURE RETURNS [RoutersFunction] = BEGIN RETURN[routersFunction]; END; <> <> <> <> <> <> SetRouterFunction: PUBLIC PROCEDURE [newFunction: RoutersFunction, numberINRBuffers: CARDINAL] RETURNS [oldFunction: RoutersFunction] = BEGIN joinTheINRServer: BOOLEAN _ FALSE; zombieINRServer: PROCESS; SetFunction: ENTRY PROCEDURE = BEGIN temp: CONDITION; oldFunction _ routersFunction; routersFunction _ newFunction; IF primaryMDS THEN BEGIN IF oldFunction=interNetworkRouting THEN BEGIN Process.SetTimeout[@temp, Process.MsecToTicks[500]]; joinTheINRServer _ iNRpleaseStop _ TRUE; zombieINRServer _ internetRouterServerFork; WHILE inrRunning DO NOTIFY internetRouterTimer; WAIT temp; ENDLOOP; END; IF newFunction=interNetworkRouting THEN BEGIN iNRpleaseStop _ FALSE; inrBufferCount _ numberINRBuffers; internetRouterServerFork _ FORK InternetRouterServer[]; END; END; -- primaryMDS clause END; -- inline of SetFunction <> SetFunction[]; IF joinTheINRServer THEN JOIN zombieINRServer; END; <> <> <> <> RoutingTableOn: PUBLIC PROCEDURE = BEGIN inrRunning _ iNRpleaseStop _ pleaseStop _ FALSE; IF primaryMDS THEN BEGIN network: Network _ DriverDefs.GetDeviceChain[]; RoutingTableActivate[]; FOR network _ network, network.next UNTIL network = NIL DO AddNetwork[network]; ENDLOOP; IF routersFunction = interNetworkRouting THEN internetRouterServerFork _ FORK InternetRouterServer[]; routingTableFork _ FORK RoutingTableUpdater[]; END; END; -- RoutingTableOn RoutingTableActivate: ENTRY PROCEDURE = INLINE BEGIN routingTableHead _ NIL; myHostID _ Router.FindMyHostID[]; probeAnInternetRouterCounter _ 0; routingTableSize _ 0; END; -- RoutingTableActivate RoutingTableOff: PUBLIC PROCEDURE = BEGIN IF primaryMDS THEN BEGIN RoutingTableDeactivate[]; JOIN routingTableFork[]; IF routersFunction = interNetworkRouting THEN JOIN internetRouterServerFork; CleanUpRoutingTable[]; END; END; -- RoutingTableOff RoutingTableDeactivate: ENTRY PROCEDURE = INLINE BEGIN iNRpleaseStop _ pleaseStop _ TRUE; NOTIFY routingTableUpdateTimer; BROADCAST responseFromInternetRouter; IF routersFunction = interNetworkRouting THEN NOTIFY internetRouterTimer; <> WHILE (probeAnInternetRouterCounter>0) DO BROADCAST responseFromInternetRouter; WAIT responseFromInternetRouter; ENDLOOP; END; -- RoutingTableDeactivate CleanUpRoutingTable: ENTRY PROCEDURE = INLINE BEGIN e, temp: RoutingTableEntry; e _ routingTableHead; WHILE e # NIL DO temp _ e; e _ e.next; --Heap.FreeNode[p: temp];-- ENDLOOP; routingTableSize _ 0; END; -- RoutingTableDeactivate <> Process.SetTimeout[@routingTableUpdateTimer, Process.MsecToTicks[60000]]; Process.SetTimeout[@responseFromInternetRouter, Process.MsecToTicks[1000]]; Process.SetTimeout[@internetRouterTimer, Process.MsecToTicks[30000]]; END. -- RoutingTableImpl module. LOG Time: January 19, 1980 4:05 PM By: Dalal Action: Split OISCPRouter into two. Time: March 13, 1980 5:11 PM By: BLyon Action: FindNetworkAndTransmit synchronously sends non-system buffers and asynchronously sends system buffers. Time: July 31, 1980 11:53 AM By: BLyon Action: replaced internetRouter with routersFunction and added Get/SetRoutersFunction. Time: August 5, 1980 4:25 PM By: BLyon Action: RoutingTable is now linked list and no such concept as primaryNetID. Time: September 13, 1980 6:15 PM By: HGM Action: Add StateChanged. Time: September 18, 1980 3:16 PM By: BLyon Action: modified StateChanged, Add/Delete Network .., removed FindPrimaryNetID. Time: January 5, 1981 4:00 PM By: BLyon Action: added EnumerateRoutingTable. Time: February 24, 1981 2:58 PM By: BLyon Action: added stuff to tell INR how many buffers to use. Time: March 19, 1981 10:38 AM By: BLyon Action: Modified FindDestinationRelativeNetID to try and not return unknownNetID if at all possible.