<> <> <> <> DIRECTORY Commander USING [ CommandProc, Register ], CommBuffer, CommDriver USING [ CreateInterceptor, DestroyInterceptor, GetNetworkChain, Interceptor, Network, RecvInterceptor ], CommDriverType USING [ Encapsulation ], IO, LupineRuntime USING [ BindingError ], Multicast, MulticastRpcControl, Pup USING [allHosts, Host, Net], PupBuffer USING [Buffer], Rope USING [ ROPE ], RPC USING [ Conversation, EncryptionKey, ExportFailed, matchAllVersions, unencrypted ], VoiceUtils USING [ CmdOrToken, CurrentPasskey, MakeRName, OwnNetAddress, Problem, ReportFR ] ; MulticastImpl: CEDAR PROGRAM IMPORTS Commander, CommDriver, IO, LupineRuntime, MulticastRpcControl, RPC, VoiceUtils EXPORTS CommBuffer -- for Encapsulation --, Multicast = { ourNet: Pup.Net; ourHost: Pup.Host; multicastOK: BOOL _ FALSE; interceptor: CommDriver.Interceptor _ NIL; <> map: PACKED ARRAY BYTE OF Pup.Host _ ALL[Pup.allHosts]; <> TurnOnMulticastForNet: PUBLIC PROC [shh: RPC.Conversation, net: Pup.Net] RETURNS [ok: BOOL] = { network: CommDriver.Network _ NIL; IF multicastOK THEN RETURN[TRUE]; FOR network _ CommDriver.GetNetworkChain[], network.next WHILE network#NIL DO IF network.pup.net = net THEN EXIT; REPEAT FINISHED => RETURN[FALSE]; ENDLOOP; ourNet _ net; ourHost _ network.pup.host; <> <> <> <> <> map _ ALL[Pup.allHosts]; interceptor _ CommDriver.CreateInterceptor[ network: network, sendMask: ALL[FALSE], sendProc: NIL, recvMask: [FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE], recvProc: MulticastForwarder, data: NIL, promiscuous: TRUE]; RETURN[multicastOK _ TRUE]; }; <> TurnOffMulticast: PUBLIC PROC[shh: RPC.Conversation] = { IF NOT multicastOK THEN RETURN; <> CommDriver.DestroyInterceptor[interceptor]; multicastOK _ FALSE; }; HandleMulticast: PUBLIC PROC [shh: RPC.Conversation, net: Pup.Net, realHost, listeningTo: Pup.Host] RETURNS [ok: BOOL] = { IF multicastOK AND net = ourNet AND realHost # Pup.allHosts AND realHost # ourHost THEN { IF map[realHost] # Pup.allHosts THEN RETURN[FALSE]; IF map[listeningTo] # Pup.allHosts THEN RETURN[FALSE]; -- prevent loops! map[realHost] _ listeningTo; <> <> RETURN[TRUE]; }; RETURN[FALSE]; }; StopHandlingMulticast: PUBLIC PROC [ shh: RPC.Conversation, realHost: Pup.Host] = { IF multicastOK AND realHost # Pup.allHosts AND realHost # ourHost THEN { map[realHost] _ Pup.allHosts; <> <> }; }; numForwarded: CARDINAL_0; -- can wrap numConsidered: CARDINAL_0; Encapsulation: PUBLIC TYPE = CommDriverType.Encapsulation; MulticastForwarder: CommDriver.RecvInterceptor = TRUSTED { pupBuffer: PupBuffer.Buffer = LOOPHOLE[buffer]; encap: LONG POINTER TO Encapsulation = @buffer.ovh.encap; listeningTo: Pup.Host; numConsidered _ numConsidered+1; IF encap.ethernetOneType # pup THEN RETURN; listeningTo _ map[encap.ethernetOneDest]; -- Must test the encapsulation, to avoid loops!! IF listeningTo = Pup.allHosts THEN RETURN; -- that host isn't in forwarding list. encap.ethernetOneDest _ listeningTo; network.pup.send[network, buffer, bytes]; }; serverInterfaceName: MulticastRpcControl.InterfaceName; serverPassword: RPC.EncryptionKey; MulticastInit: Commander.CommandProc = { ENABLE RPC.ExportFailed => { VoiceUtils.Problem["Multicast export failed", $System]; GOTO Failed; }; serverInstance: Rope.ROPE _ VoiceUtils.MakeRName[style: rName, name: VoiceUtils.CmdOrToken[cmd: cmd, key: "MulticastInstance", default: "Michaelson.Lark"]]; serverInterfaceName _ [ type: "Multicast.Lark", instance: serverInstance]; serverPassword _ VoiceUtils.CurrentPasskey[VoiceUtils.CmdOrToken[ cmd: cmd, key: "MulticastPassword", default: "MFLFLX"]]; MulticastRpcControl.UnexportInterface[!LupineRuntime.BindingError=>CONTINUE]; MulticastRpcControl.ExportInterface[ interfaceName: serverInterfaceName, user: serverInterfaceName.instance, password: serverPassword]; VoiceUtils.ReportFR["Export[Multicast.Lark, %s]", $System, NIL, IO.rope[serverInterfaceName.instance]]; IF ~TurnOnMulticastForNet[RPC.unencrypted, VoiceUtils.OwnNetAddress[].net] THEN { VoiceUtils.Problem["Multicast enabling failed", $System]; GOTO Failed; }; EXITS Failed => MulticastRpcControl.UnexportInterface[!LupineRuntime.BindingError=>CONTINUE]; }; Commander.Register["Multicast", MulticastInit, "Multicast \nInitialize and Export Multicast"]; }. Stewart, July 18, 1983 5:12 pm, fixes for RPC Packets Stewart, December 22, 1983 3:51 pm, Cedar 5 Swinehart, November 25, 1985 11:45:46 am PST, RPC Access!, Swinehart <> <> <> <> <> <> <<>> <> <> <> <<>>