<> <> <> <<>> <> DIRECTORY Endian USING [FFromCard], Booting USING [switches], Checksum USING [ComputeChecksum], GermSwap USING [], -- Needed by Booting.switches Process USING [priorityNormal, SetPriority], PupBuffer USING [Buffer, EchoStatsResponse, echoStatsVersion, noChecksum, WordsWithoutChecksum], PupSocket USING [CreateServer, Destroy, FreeBuffer, Get, GetUserBytes, Socket, Kick, SetUserSize, waitForever], PupSocketBackdoor USING [ReturnErrorNoFree, ReturnToSenderNoFree, SetDirectReceive, SetSoftwareChecksumming], PupType USING [echoStatsRequest, echoStatsReply], PupWKS USING [echo]; PupEchoServerImpl: CEDAR MONITOR IMPORTS Booting, Checksum, Endian, Process, PupBuffer, PupSocket, PupSocketBackdoor = BEGIN Buffer: TYPE = PupBuffer.Buffer; Socket: TYPE = PupSocket.Socket; pupsEchoed: LONG CARDINAL _ 0; bytesEchoed: LONG CARDINAL _ 0; pupsWithBadSoftwareChecksum: LONG CARDINAL _ 0; server: PROCESS _ NIL; pleaseStop: BOOL _ FALSE; socket: Socket _ NIL; Start: PUBLIC ENTRY PROC = { IF server # NIL THEN RETURN; pleaseStop _ FALSE; server _ FORK Server[]; }; Stop: PUBLIC ENTRY PROC = { IF server = NIL THEN RETURN; pleaseStop _ TRUE; IF server # NIL THEN { PupSocket.Kick[socket]; TRUSTED { JOIN server; }; }; server _ NIL; }; Server: PROC = { Process.SetPriority[Process.priorityNormal]; socket _ PupSocket.CreateServer[ local: PupWKS.echo, recvBuffers: 99, getTimeout: PupSocket.waitForever]; PupSocketBackdoor.SetSoftwareChecksumming[socket: socket, send: TRUE, recv: FALSE]; PupSocketBackdoor.SetDirectReceive[socket, ProcessRequest, NIL]; UNTIL pleaseStop DO b: Buffer _ PupSocket.Get[socket]; IF b # NIL THEN b _ ProcessRequest[socket, b, NIL]; IF b # NIL THEN PupSocket.FreeBuffer[b]; ENDLOOP; PupSocket.Destroy[socket]; socket _ NIL; }; ProcessRequest: PROC [socket: Socket, b: Buffer, user: REF ANY] RETURNS [Buffer] = { SELECT b.type FROM echoMe => TRUSTED { <> words: CARDINAL = PupBuffer.WordsWithoutChecksum[b.byteLength]; checksumLoc: LONG POINTER _ @b.byteLength + words; hisChecksum: WORD _ checksumLoc^; IF hisChecksum # PupBuffer.noChecksum THEN { checksum: WORD _ Checksum.ComputeChecksum[0, words, @b.byteLength]; IF checksum # hisChecksum THEN { BumpBadStats[]; b.ovh.socket _ NIL; PupSocketBackdoor.ReturnErrorNoFree[b, badChecksum, "Bad software checksum"]; RETURN[b]; }; }; b.type _ iAmEcho; BumpStats[PupSocket.GetUserBytes[b]]; b.ovh.socket _ NIL; PupSocketBackdoor.ReturnToSenderNoFree[b]; }; PupType.echoStatsRequest => { b.type _ PupType.echoStatsReply; b.echoStats _ [ version: PupBuffer.echoStatsVersion, pupsEchoed: Endian.FFromCard[pupsEchoed]]; PupSocket.SetUserSize[b, SIZE[PupBuffer.EchoStatsResponse]]; b.ovh.socket _ NIL; PupSocketBackdoor.ReturnToSenderNoFree[b]; }; ENDCASE => NULL; RETURN[b]; }; BumpBadStats: ENTRY PROC = INLINE { pupsWithBadSoftwareChecksum _ pupsWithBadSoftwareChecksum.SUCC; }; BumpStats: ENTRY PROC [bytes: NAT] = INLINE { bytesEchoed _ bytesEchoed + bytes; pupsEchoed _ pupsEchoed.SUCC; }; IF ~Booting.switches[c] THEN Start[]; END.