DIRECTORY Process USING [Abort, Pause, SecondsToTicks], XNS USING [Address, broadcastHost, Host, Net, Socket], XNSBuf USING [Buffer], XNSEchoBuf USING [Buffer, hdrBytes], XNSReachable USING [], XNSRouter USING [Enumerate, GetHops, RoutingTableEntry, unreachable], XNSRouterPrivate USING [Network, Route], XNSSocket USING [AllocBuffer, Create, Destroy, FreeBuffer, Get, Handle, Put, SetGetTimeout, SetNoErrors, SetRemoteAddress, SetUserBytes], XNSWKS USING [echo]; XNSReachableImpl: CEDAR MONITOR IMPORTS Process, XNSRouter, XNSRouterPrivate, XNSSocket EXPORTS XNSReachable ~ BEGIN doIt: BOOL _ FALSE; firstHopOnly: BOOL _ TRUE; initialTimeoutMilliseconds: INT _ 250; perHopTimeoutMilliseconds: INT _ 250; maxTries: CARDINAL _ 10; numQuickTries: CARDINAL _ 2; EnsureHostReachable: PUBLIC PROC [hisAddress: XNS.Address] RETURNS [reachable: BOOL] ~ { network: XNSRouterPrivate.Network; b: XNSBuf.Buffer _ NIL; tempSocket: XNSSocket.Handle; pingAddress: XNS.Address; destHops: CARDINAL; getTimeout, getTimeoutIncrement: INT; IF NOT doIt THEN RETURN [TRUE]; destHops _ XNSRouter.GetHops[hisAddress.net]; SELECT destHops FROM XNSRouter.unreachable => RETURN [FALSE]; 0 => RETURN [TRUE]; ENDCASE; IF firstHopOnly THEN { [network, pingAddress.host] _ XNSRouterPrivate.Route[hisAddress]; IF network.xns.translation = NIL THEN RETURN [TRUE]; pingAddress.net _ network.xns.net; pingAddress.socket _ XNSWKS.echo; getTimeout _ initialTimeoutMilliseconds; getTimeoutIncrement _ initialTimeoutMilliseconds } ELSE { pingAddress _ hisAddress; pingAddress.socket _ XNSWKS.echo; getTimeout _ initialTimeoutMilliseconds; getTimeoutIncrement _ destHops * perHopTimeoutMilliseconds }; tempSocket _ GetTempSocket[]; XNSSocket.SetRemoteAddress[tempSocket, pingAddress]; reachable _ FALSE; FOR try: CARD IN [1..maxTries] DO IF try > numQuickTries THEN getTimeout _ getTimeout + getTimeoutIncrement; XNSSocket.SetGetTimeout[tempSocket, getTimeout]; IF b = NIL THEN b _ XNSSocket.AllocBuffer[tempSocket]; SendRequest[tempSocket, b]; b _ XNSSocket.Get[tempSocket]; IF (b # NIL) AND (b.hdr1.source.host = pingAddress.host) THEN { reachable _ TRUE; EXIT }; ENDLOOP; IF b # NIL THEN XNSSocket.FreeBuffer[b]; PutTempSocket[tempSocket]; }; SendRequest: PROC [socket: XNSSocket.Handle, b: XNSBuf.Buffer] ~ { eB: XNSEchoBuf.Buffer; TRUSTED { eB _ LOOPHOLE[b] }; eB.hdr1.type _ echo; eB.hdr2 _ [filler~0, type~request]; XNSSocket.SetUserBytes[b, XNSEchoBuf.hdrBytes]; XNSSocket.Put[b] }; theTempSocket: XNSSocket.Handle _ NIL; GetTempSocket: ENTRY PROC RETURNS [socket: XNSSocket.Handle] ~ { ENABLE UNWIND => NULL; IF theTempSocket = NIL THEN RETURN [XNSSocket.Create[]]; socket _ theTempSocket; theTempSocket _ NIL; XNSSocket.SetNoErrors[handle~socket, noErrors~FALSE]; }; PutTempSocket: ENTRY PROC [socket: XNSSocket.Handle] ~ { ENABLE UNWIND => NULL; XNSSocket.SetNoErrors[handle~socket, noErrors~TRUE]; IF theTempSocket # NIL THEN XNSSocket.Destroy[socket] ELSE theTempSocket _ socket; }; worker: PROCESS _ NIL; workerSweepSeconds: INT _ 150; Start: ENTRY PROC ~ { ENABLE UNWIND => NULL; IF worker = NIL THEN worker _ FORK Worker[]; }; Stop: ENTRY PROC ~ { ENABLE UNWIND => NULL; IF worker # NIL THEN TRUSTED { Process.Abort[worker]; JOIN worker; worker _ NIL }; }; Worker: PROC ~ { EachEntry: PROC[net: XNS.Net, entry: XNSRouter.RoutingTableEntry] ~ { network: XNSRouterPrivate.Network; host: XNS.Host; [network, host] _ XNSRouterPrivate.Route[ [net~net, host~XNS.broadcastHost, socket~XNSWKS.echo]]; IF network.xns.translation = NIL THEN RETURN; [] _ network.xns.getEncapsulation[network, host]; }; DO XNSRouter.Enumerate[proc~EachEntry]; Process.Pause[Process.SecondsToTicks[workerSweepSeconds]]; ENDLOOP; }; Start[]; END. NXNSReachableImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Demers, December 2, 1986 0:47:06 am PST This is a kludge to get XNS stream creation to work okay from 3Mb nets despite the short timeout of the gateway translation caches. All very ad hoc. Daemon to ping all routers on directly connected nets ΚK˜codešœ™Kšœ Οmœ1™